I am creating a table that at first keyID column is NOT in AUTO INCREMENT since i am going to insert a data that came from an old database where the keyID is already been set to each rows and it's not possible to be changed. So is it possible that i can set the column to AUTO INCREMENT after all the data has been moved? I've seen this:
ALTER TABLE tbl_name MODIFY COLUMN keyID_id INT auto_increment
So if ever i set the keyID to auto increment after i moved all the data, so for example 10 rows has been transferred and some numbers may be missing for example, keyIDs: 1,2,3,5,6,7...15
can I assume that after i set the keyID to auto increment, the next row will be keyID 16?
The first thing to say here is that SQLite has no syntax to change the settings of a column. You are forced to rename your original table, create a new table with the schema you want and then copy from the renamed table into the new one.
So your code to add the AUTOINCREMENT flag to your table is something like this
SQLiteCommand cmd = new SQLiteCommand();
cmd.Connection = yourConnection;
cmd.CommandText = "ALTER TABLE tblName RENAME TO tmp_tblName";
cmd.ExecuteNonQuery();
cmd = new SQLiteCommand(#"
CREATE TABLE tblName
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
AnotherField NVARCHAR(100) NOT NULL)", cnn);
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO tblName (ID, AnotherField) SELECT ID, AnotherField FROM tmp_tblName";
cmd.ExecuteNonQuery();
Now, when you create a table with the AUTOINCREMENT SQLite add a new row to an internal table called sqlite_sequence. This table could be read by the usual ADO.NET classes
cmd.CommandText = "SELECT seq FROM sqlite_sequence WHERE name = 'tblName'";
int lastInsertedValue = Convert.ToInt32(cmd.ExecuteScalar());
Console.WriteLine(lastInsertedValue);
If your run this test code you will see that the value for the field seq is equal to the maximum value inserted in the PRIMARY KEY field.
After this if you try to insert a new record in your table you will see that the AUTOINCREMENT flag has started to work as expected and your new record will receive the next value from the sequence....
Even though the SQLite documentation and some posts state that the alter table command in SQLite is very limited and should not allow making such modifications, it seems that it's still possible to alter PK properties. What worked for me was:
Create a table with CREATE TABLE "test" (Field1INTEGER,Field2TEXT,)
Insert arbitrary data
Change column definition for column Field1 with DB Browser for SQLite
Subsequent inserts should then auto increment the IDs in the column Field1.
I must admit that it might not be suitable if there's the requirement to do this programatically, but if some manual steps are acceptable, it may be a solution.
Related
I have looked at all the similar questions on this topic but none seem to work for me.
When I try to run my application, I get the following error:
System.Data.SqlClient.SqlException: 'Cannot insert the value NULL into column 'Id', table 'C:\FINALLY\DATABASE.MDF.dbo.loginTB'; column does not allow nulls. INSERT fails.
Here is my code:
private void btnContinued_reg_Click(object sender, EventArgs e)
{
SqlConnection cn = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\finally\DataBase.mdf;Integrated Security=True;Connect Timeout=30");
SqlCommand cmd= new SqlCommand("insert into loginTB(username,password)values('" + txtUserName_reg.Text + "','" + txtPaswword_reg.Text + "')",cn);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
MessageBox.Show("good");
}
What am I doing wrong?
A snapshot of my code:
The problem does not indicate a connection problem at all. It seems that you are trying to insert a record into a table, and you are trying to pass null as the id, which gives you the error.
My guess would be the error is in the definition of that table loginTB, you make sure the column id has the property IDENTITY, since you are using SQL Server.
An example would be like this:
CREATE TABLE new_employees
(
id_num int PRIMARY KEY IDENTITY(1,1),
fname varchar (20),
minit char(1),
lname varchar(30)
);
Identity columns can be used for generating key values. The identity property on a column guarantees the following:
Each new value is generated based on the current seed & increment.
Each new value for a particular transaction is different from other concurrent transactions on the table.
The identity property on a column does not guarantee the following:
Uniqueness of the value
Uniqueness must be enforced by using a PRIMARY KEY or UNIQUE constraint or UNIQUE index.
Follow up answer of previous answers.
If you already created a table and want to modify it to work correctly:
Go to the table properties from SSMS tool and select the identity column and save the properties. Identity column must be marked as not nullable.
I used idcorrectcounter(int) to write new IDs of cells and i(int) to identify which row will be updated.
I used (Convert.ToInt32(txtrid.Text)-2) to execute code according to row numbers.
I want to line up ID cells after deleting and this code works fine until one of the ID cells is "1".
int idcorrectcounter=0;
for (int i = 0; i <= (Convert.ToInt32(txtrid.Text)-2); i++)
{
idcorrectcounter++;
connect.Open();
SqlCommand idcorrect = new SqlCommand("Update bighall1record set ID="
+ idcorrectcounter.ToString()
+ " where ID='"
+ dataGridView1.Rows[i].Cells[0].Value.ToString()
+ "'", connect);
idcorrect.ExecuteNonQuery();
connect.Close();
showdata("Select *from bighall1record");
}
idcorrectcounter=0;
i think you are not setting a unique "identifier for ID" here.
Reset auto increment after deleting a table row
It is often the case that a column such as the ID column on a table will auto increment. This simply means that the next insert into the table will have an ID that is one more then the previous one and therefore all ID's will be unique.
However, if you delete a row from the table, the table will auto increment as if the row had not been deleted at all. The result is a gap in the sequence of numbers. This is normally not that much of an issue, but you may want to reset the auto increment field.
There are two simple steps in resetting an auto increment field:
Find the highest number in the auto increment field
To find the highest number, run the following SQL command:
SELECT MAX( column ) FROM table ;
Replace 'column' with the name of the auto incrementing column. Replace table with the name of the table.
Reset the auto increment field
The next step is to take the number that you get from the first command and auto increment from there. So add one to that number and run the following command:
ALTER TABLE table AUTO_INCREMENT = number;
Replacing 'number' with the result of the previous command plus one and replacing table with the table name.
If you deleted all the rows in the table, then you could run the alter table command and reset it to 0.
I am using a temporary table to display data in a datagridview. When the data in the datagridview is edited, I am trying to update the temporary table. This is the code inside the dataGridView1_RowValidated method that I'm using to do so:
MySqlDataAdapter adapter = new MySqlDataAdapter("select * from all_plants_temp", con);
MySqlCommandBuilder builder = new MySqlCommandBuilder(adapter);
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.Update(changes);
((DataTable)dataGridView1.DataSource).AcceptChanges();
However, I am running into the following error whenever I leave the edited row:
Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not return any key column information.
From what the error suggests (along with every website I visited), I need to include a primary key in the table. However, I already have an int auto-incrementing primary key. This is the code that I used to create the temporary table, along with the relevant code of the original non-temporary table.
ALTER TABLE all_plants ADD COLUMN plantID INT PRIMARY KEY AUTO_INCREMENT;
CREATE TEMPORARY TABLE all_plants_temp SELECT * FROM all_plants;
Can someone tell me the fault in my code? Any help is appreciated.
As said before I belive your temporary table does not have a primary key.
Try using this query. It will create the temporary table with a Primary Key. Change YourPk with what you want.
CREATE TEMPORARY TABLE all_plants_temp
(YourPk int(10) NOT NULL, PRIMARY KEY (YourPk)) SELECT * from all_plants;
One of the columns, called ID my SQL Server database is auto generated. When I insert a new row(s) using SqlDataAdapter.Update(table) and accept the changes SqlDataAdapter.AcceptChanges(), the ID column in table is set to -1, instead of new auto generated ID value. Database insertion work and new rows(s) are inserted into database with sequential auto generated IDvalues.
How do I force SqlDataAdapter or SqlDataTable to get back correct ID values ?
I have solved the issue. For future reference
operationDBAdapter.InsertCommand.CommandText = "INSERT INTO Operations(operationType,agentID,resetTime,description,enabled,logLevel) VALUES
(#operationType,#agentID,#resetTime,#description,#enabled,#logLevel);
**SELECT ID,operationType,agentID,resetTime,description,enabled,logLevel
FROM Operations WHERE (ID = SCOPE_IDENTITY())**"
After the insertion command, just select rows from the same table.
I have found a strange phenomena on MSSQL server.
Let say we have a table:
CREATE TABLE [testTable]
(
[ID] [numeric](11, 0) NOT NULL,
[Updated] [datetime] NULL,
PRIMARY KEY (ID)
);
I do a simple select based on Updated field:
SELECT TOP 10000 ID, Updated
FROM testTable
WHERE Updated>='2013-05-22 08:55:12.152'
ORDER BY Updated
And now comes the fun part: how can I have in result set double records - I mean same ID in 2 records with different Updated value.
For me it seems to be, that the Updated datetime value was changed and it was included one more time in result set. But is it possible?
UPDATE:
Source code I using for downloading data from SQL server:
using (SqlCommand cmd = new SqlCommand(sql, Connection) { CommandTimeout = commandTimeout })
{
using (System.Data.SqlClient.SqlDataAdapter adapter = new System.Data.SqlClient.SqlDataAdapter(cmd))
{
DataTable retVal = new DataTable();
adapter.Fill(retVal);
return retVal;
}
}
Connection = SqlConnection
sql = "SELECT TOP 10000 ...."
Your question seems to lack some details but here's my ideas.
The first case I'd think of would be that you are somehow selecting those IDs twice (could be a join, group by, ...). Please manually check inside your table (in MSSQL Server rather than inside a function or method) to see if there is dupplicated IDs. If there is, the issue is that your Primary Key hasn't been set correctly. Otherwise, you will need to provide all the relevant code that is used to select the data in order to get more help.
Another case might be that someone or something altered the primary key so it is on both ID and Updated, allowing the same ID to be inserted twice as long as the Updated field doesn't match too.
You may also try this query to see if it gets dupplicated IDs inside your context:
SELECT ID
from testTable
ORDER BY ID
I hope this helps.