I try to move rows that expired from one table to another with this:
MySqlConnection connect = new MySqlConnection(connectionStringMySql);
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = connect;
cmd.Connection.Open();
string commandLine = #"INSERT INTO history SELECT clientid,userid,startdate,
enddate,first,city,imgurl,phone,type,seen
FROM events WHERE startdate<now();";
cmd.CommandText = commandLine;
cmd.ExecuteNonQuery();
cmd.Connection.Close();
The table are exactly the same (in each table I have id column with primary key, with auto increment) and when I run it i get this exception:
Column count doesn't match value count at row 1
Any idea why it crash?
The reason why you get the error is because the number of column on the table doesn't match on the number of values being inserted. This is usual when you have an auto-incrementing column on the table you are inserting.
In order to fix the problem, you need to specify the column name where the values will be inserted. Example,
INSERT INTO history (col1, col2,....) // << specify column names here
SELECT clientid, userid, startdate, enddate, first,
city, imgurl, phone, type, seen
FROM events
WHERE startdate < now()
I'm not pretty sure of the column names of table history that's why you need to change the column names to your valid names on your table.
For instance you have an auto-incrementing column on table history and you want to leave the query as is, you can pass NULL on the SELECT statement just to match the total number of columns to the total number of values. Example,
INSERT INTO history
SELECT NULL, clientid, userid, startdate, enddate, first,
city, imgurl, phone, type, seen
FROM events
WHERE startdate < now()
Keep in mind that in the case you won't specify the column names, the order of the values does matter.
Try :
string commandLine = #"INSERT INTO history (clientid,userid,startdate,enddate,first,city,imgurl,phone,type,seen) SELECT clientid,userid,startdate,enddate,first,city,imgurl,phone,type,seen FROM events WHERE startdate<now();";
Related
I need some correction with my query in C# & SQL Server.
I have a table called LoggedIn with name, password and clockin columns. I want it to insert into the table where name and password is from another table AND the clockin is the current time now.
string belepve = "INSERT INTO LoggedIn VALUES (SELECT name, password FROM Login WHERE password =" + Kod.login1 +" ,#MyDate";
SqlCommand command4 = new SqlCommand(belepve, con);
command4.Parameters.AddWithValue("#MyDate", DateTime.Now);
And then I just Execute the query.
There are multiple issues here.
First is the second parameter should also go as SqlParameter.
Second you have missing parenthesis at end.
Third you would need to specify the column names in which values should go in LoggedIn table.
Your working code would be something like:
string belepve = #"INSERT INTO LoggedIn (name,password,LoginDate)
VALUES (SELECT name,password,#MyDate
FROM Login
WHERE password =#Password
)";
SqlCommand command4 = new SqlCommand(belepve, con);
command4.Parameters.AddWithValue("#MyDate", DateTime.Now);
command4.Parameters.AddWithValue("#Password", Kod.login1);
Assuming that you have columns in LoggedIn table as named name,password and LoginDate, you might need to adjust the column names which you have actually in your table.
If you have same number of columns which you are already selecting then you can do it more simple like following:
SELECT name,password,#MyDate
INTO LoggedIn
FROM Login
WHERE password =#Password
But you need to be careful in the order of columns selecting otherwise value might go in different column than in what is expected.
Hope it helps.
I have a C# program that connects to a remote mysql server and store date in a database on it.
In my db I have a column which I need it to have the CURRENT_TIMESTAMP of the server so I set the type of the column in my db to timestamp and the default value to CURRENT_TIMESTAMP the problem is when I ignore this column in my command I get this error "column count doesn't match value count at row 1" and if I send empty value, the value in the db becomes like this "0000-00-00 00:00:00".
here is my code
DBConnectMySQL.DBCommand.CommandText =
"INSERT INTO tbCard VALUES (#id,#Phone, #username, #CardDate)";
DBConnectMySQL.DBCommand.Parameters.AddWithValue("#id", "");
DBConnectMySQL.DBCommand.Parameters.AddWithValue("#Phone", number);
DBConnectMySQL.DBCommand.Parameters.AddWithValue("#username", UserName);
DBConnectMySQL.DBCommand.Parameters.AddWithValue("#CardDate", ""); // here is the problem
DBConnectMySQL.DBCommand();
DBConnectMySQL.DBCommand.Parameters.Clear();
I don't want to send the current time and date of the machine because I want to use the server time.
Specify which columns you want to insert and omit the column:
DBConnectMySQL.DBCommand.CommandText = "INSERT INTO tbCard(id, Phone, username) VALUES (#id,#Phone, #username)";
DBConnectMySQL.DBCommand.Parameters.AddWithValue("#id", "");
DBConnectMySQL.DBCommand.Parameters.AddWithValue("#Phone", number);
DBConnectMySQL.DBCommand.Parameters.AddWithValue("#username", UserName);
If you use an INSERT statement without saying which columns receives the values then you need to pass all the values for all the columns in the order in which the columns are defined in the table.
To avoid this problem just specify the column's names before the VALUES statement
string cmdText = #"INSERT INTO tbCard (col1, col2, col3)
VALUES (#id, #Phone, #username)";
DBConnectMySQL.DBCommand.CommandText = cmdText;
Also, if the ID column is an AUTO-INCREMENT column, then you shouldn't pass also this column and its value.
I have a database with some columns and one of that is called ID (datatype = int).
I need to know the value of the ID of the last row (for last row I mean the last created).
I tried this, but it gives a runtime error:
string query = "SELECT * FROM Customer WHERE ID = (SELECT MAX(ID) FROM Customer)";
SqlCeCommand comSelect = new SqlCeCommand(query, connection);
SqlCeDataReader rdr = comSelect.ExecuteReader();
int ID = rdr.GetInt32(6);
(GetInt32(6) because ID is the 6th column)
Thanks all, and sorry for my english.
P.S.
Customer is my table and ID are set in ascending order. The first row created has ID = 0 the second ID = 1 etc.
I need to know the last id because when I create a new customer I want to set his ID to previous customer ID+1
Errors:
Exception of type 'System.Data.SqlServerCe.SqlCeException' in System.Data.SqlServerCe.dll unhandled in user code
Given the fact that probably there is no problem with concurrency you could simply get the last ID with an ExecuteScalar call
string query ="SELECT MAX(ID) FROM Customer";
SqlCeCommand comSelect = new SqlCeCommand(query, connection);
int ID = (int)comSelect.ExecuteScalar();
ExecuteScalar returns the first column of the first row in the result set.
The query SELECT MAX(ID) returns just one row with only one column. So ExecuteScalar fits perfectly in this scenario. No need to use an ExecuteReader
However, the correct way to handle your autoincrement scenario is to use an IDENTITY column that will automatically set the next value for you when you insert a new record.
In this situation you have marked the ID column with the IDENTITY property to TRUE and then you insert your data in the table Customer without passing any value for the ID column. After the insert you retrieve immediately the value assigned by the database to your ID column
Pseudocode
string query ="INSERT INTO Customers (Name, Address, .....) VALUES (.....)";
SqlCeCommand comInsert = new SqlCeCommand(query, connection);
comInsert.ExecuteNonQuery();
query ="SELECT ##IDENTITY";
SqlCeCommand comSelect = new SqlCeCommand(query, connection);
int ID = (int)comSelect.ExecuteScalar();
If you are setting the Id and you may have other users its better to save the new data and get the I'd, or whole new object, returned from the db by the code saving the row. If you try and keep track of user ids other users could add new items and mess things up.
If you have to get last I'd from the db then you can use #inserted in your sql to get the last row added.
I am creating a winform application in c#.and using sql database.
I have one table, employee_master, which has columns like Id, name, address and phone no. Id is auto increment and all other datatypes are varchar.
I am using this code to get the next auto increment value:
string s = "select max(id) as Id from Employee_Master";
SqlCommand cmd = new SqlCommand(s, obj.con);
SqlDataReader dr = cmd.ExecuteReader();
dr.Read();
int i = Convert.ToInt16(dr["Id"].ToString());
txtId.Text = (i + 1).ToString();
I am displaying on a textBox.
But when last row from table is deleted, still I get that value which is recently deleted in textbox
How should I get the next autoincrement value?
To get the next auto-increment value from SQLServer :
This will fetch the present auto-increment value.
SELECT IDENT_CURRENT('table_name');
Next auto-increment value.
SELECT IDENT_CURRENT('table_name')+1;
------> This will work even if you add a row and then delete it because IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope.
try this:
SELECT IDENT_CURRENT('tbl_name') + IDENT_INCR('tbl_name');
If you are using Microsoft SQL Server. Use this statement to get current identity value of table. Then add your seed value which you have specified at time of designing table if you want to get next id.
SELECT IDENT_CURRENT(<TableName>)
As for me, the best answer is:
dbcc checkident(table_name)
You will see two values (probably same)
current identity value , current column value
When you delete a row from the table the next number will stay the same as it doesnt decrement in any way.
So if you have 100 rows and you deleted row 100. You would have 99 rows but the next number is still going to be 101.
select isnull((max(AddressID)+1),1) from AddressDetails
the max(id) will get you maximum number in the list pf employee_master
e.g. id = 10, 20, 100 so max will get you 100
But when you delete the record it must have been not 100
So you still get 100 back
One important reason for me to say this might be the issue because you are not using order by id in your query
For MS SQL 2005 and greater:
Select Cast(IsNULL(last_value,seed_value) As Int) + Cast(increment_value As Int) As NextID
From sys.identity_columns
WHERE NAME = <Table_Name>
Just a thought, if what you wanted was the last auto-number that you inserted on an already open connection try using:
SELECT ##IDENTITY FROM...
from that connection. That's the best way to keep track of what has just happened on a given connection and avoids race conditions w/ other connections. Getting the maximum identity is not generally feasible.
SqlConnection con = new SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=databasename;User ID=sa;Password=123");
con.Open();
SqlCommand cmd = new SqlCommand("SELECT TOP(1) UID FROM InvoiceDetails ORDER BY 1 DESC", con);
SqlDataReader reader = cmd.ExecuteReader();
//won't need a while since it will only retrieve one row
while (reader.Read())
{
string data = reader["UID"].ToString();
//txtuniqueno.Text = data;
//here is your data
//cal();
//txtuniqueno.Text = data.ToString();
int i = Int32.Parse(data);
i++;
txtuid.Text = i.ToString();
}
I know that in Oracle I can get the generated id (or any other column) from an inserted row as an output parameter.
Ex:
insert into foo values('foo','bar') returning id into :myOutputParameter
Is there a way to do the same, but using ExecuteScalar instead of ExecuteNonQuery?
I don't want to use output parameters or stored procedures.
ps: I'm using Oracle, not sql server!!!
If you are on oracle, you have to use ExecuteNonQuery and ResultParameter. There is no way to write this as query.
using (OracleCommand cmd = con.CreateCommand()) {
cmd.CommandText = "insert into foo values('foo','bar') returning id into :myOutputParameter";
cmd.Parameters.Add(new OracleParameter("myOutputParameter", OracleDbType.Decimal), ParameterDirection.ReturnValue);
cmd.ExecuteNonQuery(); // an INSERT is always a Non Query
return Convert.ToDecimal(cmd.Parameters["myOutputParameter"].Value);
}
Oracle uses sequences as for his identity columns, if we may say so.
If you have set a sequence for your table primary key, you also have to write a trigger that will insert the Sequence.NextValue or so into your primary key field.
Assuming that you are already familiar with this concept, simply query your sequence, then you will get your answer. What is very practiced in Oracle is to make yourself a function which will return an INT, then within your function, you perform your INSERT. Assuming that you have setup your trigger correctly, you will then be able to return the value of your sequence by querying it.
Here's an instance:
CREATE TABLE my_table (
id_my_table INT PRIMARY KEY
description VARCHAR2(100) NOT NULL
)
CREATE SEQUENCE my_table_seq
MINVALUE 1
MAXVALUE 1000
START WITH 1
INCREMENT BY 2
CACHE 5;
If you want to manage the auto-increment yourself, here's how:
INSERT INTO my_table (
id_my_table,
description
) VALUES (my_table_seq.NEXTVAL, "Some description");
COMMIT;
On the other hand, if you wish not to care about the PRIMARY KEY increment, you may proceed with a trigger.
CREATE OR REPLACE TRIGGER my_table_insert_trg
BEFORE INSERT ON my_table FOR EACH ROW
BEGIN
SELECT my_table_seq.NEXTVAL INTO :NEW.id_my_table FROM DUAL;
END;
Then, when you're inserting, you simply type the INSERT statement as follows:
INSERT INTO my_table (description) VALUES ("Some other description");
COMMIT;
After an INSERT, I guess you'll want to
SELECT my_table_seq.CURRVAL
or something like this to select the actual value of your sequence.
Here are some links to help:
http://www.orafaq.com/wiki/Sequence
http://www.orafaq.com/wiki/AutoNumber_and_Identity_columns
Hope this helps!
You can use below code.
using (OracleCommand cmd = conn.CreateCommand())
{
cmd.CommandText = #"INSERT INTO my_table(name, address)
VALUES ('Girish','Gurgaon India')
RETURNING my_id INTO :my_id_param";
OracleParameter outputParameter = new OracleParameter("my_id_param", OracleDbType.Decimal);
outputParameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add(outputParameter);
cmd.ExecuteNonQuery();
return Convert.ToDecimal(outputParameter.Value);
}
one possible way if one can add one column named "guid" to the table :
when inserting one record from c#, generate a guid and write it to the guid column.
then perform a select with the generated guid, and you have got the id of inserted record :)
Select t.userid_pk From Crm_User_Info T
Where T.Rowid = (select max(t.rowid) from crm_user_info t)
this will return your required id