Number of query values and destination fields are not the same (Union) - sql

Running into this SQL error - number of query values and destination fields are not the same (Union). Using an Access database. The programList table has just two fields in it - userID and programID. Using parameters in my cs file. Here is the complete method:
public void AddProgramList (string program, int userID)
{
dbConnection.Open();
string sqlStmt = "INSERT INTO programs (program) ";
sqlStmt += "VALUES (#program)";
string sqlStmt2 = "INSERT INTO programList (userID, programID) " +
"SELECT userID " +
"FROM users" +
"WHERE userID = #userID " +
"UNION " +
"SELECT programID " +
"FROM programs" +
"WHERE program = #program;";
OleDbCommand dbCommand = new OleDbCommand(sqlStmt, dbConnection);
OleDbParameter param = new OleDbParameter("#program", program);
dbCommand.Parameters.Add(param);
dbCommand.Parameters.Add(new OleDbParameter("#userID", userID));
OleDbCommand dbCommand2 = new OleDbCommand(sqlStmt2, dbConnection);
OleDbParameter param2 = new OleDbParameter("#program", program);
dbCommand2.Parameters.Add(param2);
dbCommand2.Parameters.Add(new OleDbParameter("#userID", userID));
dbCommand.ExecuteNonQuery();
dbCommand2.ExecuteNonQuery();
dbConnection.Close();
}

If you printed out the SQL, you would see:
INSERT INTO programList (userID, programID) " +
SELECT userID FROM usersWHERE userID = #userID UNION SELECT programID FROM programsWHERE program = #program;
The error should be pretty obvious. You probably don't have a table called usersWHERE.
As I look at the problem, you are trying to insert two columns. So, I think you intend:
INSERT INTO programList (userID, programID)
SELECT userID, programID
FROM users, programs
WHERE userID = #userID AND program = #program;
Or, more simply:
INSERT INTO programList (userID, programID)
SELECT #userID, programid
FROM programs
WHERE program = #program;

Related

update table statement - Violation of Primary Key constraint

I tried this c# update if record exists else insert new record to update my table, if records exists.
But I run into the exception: "Violation of Primary Key constraint". Because of this line cmdCount.Parameters.AddWithValue("#local_programs_id", local_programs_id); and because there's already a value for local_programs_id in the table
What have I done wrong?
Thanks a lot.
SqlConnection connection = new SqlConnection(sqlConnection_String);
SqlCommand cmdCount = new SqlCommand("SELECT count(*) FROM " + datenbankname + " WHERE local_programs_id = #local_programs_id" , connection);
cmdCount.Parameters.AddWithValue("#local_programs_id", local_programs_id);
connection.Open();
int count = (int)cmdCount.ExecuteScalar();
Console.WriteLine("count1 " + count);
if (count > 0)
{
SqlCommand updateCommand = new SqlCommand("UPDATE " + datenbankname +
" SET local_programs_Id = #local_programs_Id, " +
"program_name = #program_name, " +
"publisher_name = #publisher_name, " +
"program_version = #program_version, " +
"install_dir = #install_dir, " +
"uninstall_dir = #uninstall_dir, " +
"inserted_at = #inserted_at, " +
"direct_link_available = #direct_link_available", connection);
updateCommand.Parameters.AddWithValue("#local_programs_Id", local_programs_id);
updateCommand.Parameters.AddWithValue("#program_name", program_names);
updateCommand.Parameters.AddWithValue("#publisher_name", publisher_names);
updateCommand.Parameters.AddWithValue("#program_version", program_version);
updateCommand.Parameters.AddWithValue("#install_dir", install_location);
updateCommand.Parameters.AddWithValue("#uninstall_dir", uninstall_location);
updateCommand.Parameters.AddWithValue("#inserted_at", DateTime.Now);
updateCommand.Parameters.AddWithValue("#direct_link_available", direct_link_available);
int rowsUpdated = updateCommand.ExecuteNonQuery();
Console.WriteLine("rowsUpdated " + rowsUpdated);
}
else
{
Console.WriteLine("inserted1 ");
string query = "INSERT INTO " + datenbankname + " (local_programs_Id, program_name, publisher_name, program_version, install_dir, uninstall_dir, inserted_at)";
query += " VALUES (#local_programs_Id, #program_name, #publisher_name, #program_version, #install_dir, #uninstall_dir, #inserted_at)";
SqlCommand insertCommand = new SqlCommand(query, connection);
insertCommand.Parameters.AddWithValue("#local_programs_Id", local_programs_id);
insertCommand.Parameters.AddWithValue("#program_name", program_names);
insertCommand.Parameters.AddWithValue("#publisher_name", publisher_names);
insertCommand.Parameters.AddWithValue("#program_version", program_version);
insertCommand.Parameters.AddWithValue("#install_dir", install_location);
insertCommand.Parameters.AddWithValue("#uninstall_dir", uninstall_location);
insertCommand.Parameters.AddWithValue("#inserted_at", DateTime.Now);
int rowsInserted = insertCommand.ExecuteNonQuery();
}
You don't have a where filter on your update statement and you are updating the primary key column. You're essentially doing
Check if there is a row with X primary key value
If there is then update every row to have that primary key value.
If not then insert.
You should not be updating the primary key ever, even in your case where it isn't supposed to be changing. There are lots of annoying behaviour that could come from this, one that springs to mind is where this primary key is referenced in a foreign key in another table - this update statement would put locks on the other table (potentially a full table lock if it's not indexed).
You also should not be using a count(*) to determine whether the row exists. This will only tell you if the row exists at that point in time and is visible to your session (you can't see non-committed transactions). Most RDBMSs have a MERGE operation you can use for this behaviour, have a look at your RDBMSs docs for it. Alternatively, it might be okay to optimistically try the insert statement and if it throws a duplicate row error then you do the update statement.

Insert value locating particular column in Microsoft SQL server

I want to insert value locating particular column. I used following script.
"INSERT INTO tbl_user VALUES(UserID = '" + myUser.ID + "', UserName = '" + myUser.Name + "', Password = '" + myUser.Password + "', UserType = '" + myUser.Type + "')";
But it gives me the following error.
Incorrect syntax near '='.
There may some other way to do this task. But I want to do it in this way. Can I?
Always use parameterized query anyway correct your current attempt as below
"INSERT INTO tbl_user (UserID, UserName, UserName , UserType)
VALUES('" + myUser.ID + "','" + myUser.Name + "', '" + myUser.Password + "', '" + myUser.Type + "')";
RECOMMENDED Way is to Go with parameterized query always to prevent SQL Injection Attacks
SqlCommand cmd = new SqlCommand("INSERT INTO tbl_user (UserID, UserName, UserName , UserType)
VALUES (#UserID,...)", connections)
cmd.Parameters.AddWithValue("#UserID", myUser.ID)
...
No, you can't do it your way.
It is:
INSERT INTO table (column1_name,... ) VALUES (column1_value,...) ;
https://www.techonthenet.com/sql_server/insert.php

Merge query from datagridview to database not executing sql, vb.net

I'm having a problem executing a merge query from to update or insert values from a DataGridView table into a sql server database table. Here is my code below, it doesn't give me any errors or stoppages, however I recently noticed that it has been creating completely rows in my database table dbo.schedule which contain all NULL values even that key location, could someone please help me? I'm not very familiar with merge queries in sql so please point out issues with my syntax:
Dim query As String = String.Empty
query &= "DECLARE #TaskID nvarchar(8), #Task nvarchar(50), #Start_date datetime, #Due_date datetime, #Complete bit, #Task_Manager nvarchar(8), #JRID nvarchar(10), #Entered_By char(50), #Time_Entered datetime;"
query &= "MERGE INTO schedule USING (VALUES (#TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered)) AS t(TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered) "
query &= "ON schedule.TaskID = #TaskID WHEN MATCHED THEN"
query &= " UPDATE SET schedule.TaskID = t.TaskID, schedule.Task=t.Task, schedule.start_date=t.start_date, schedule.due_date=t.due_date, schedule.complete=t.complete, schedule.task_manager=t.task_manager, "
query &= "schedule.JRID=t.JRID, schedule.Entered_by=t.Entered_by, schedule.Time_Entered=t.Time_Entered"
query &= " WHEN NOT MATCHED THEN INSERT (TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered)"
query &= " VALUES (#TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered);"
Using conn As New SqlConnection(dbLocations(0, 1))
Using comm As New SqlCommand()
With comm
For Each row As DataGridViewRow In MainSchedule.DataGridView1.Rows
If Not (row.Cells(0).Value = Nothing) Then
.Parameters.Clear()
.Connection = conn
.CommandType = CommandType.Text
.CommandText = query
insertcommand.Parameters.AddWithValue("#TaskID", TNn)
insertcommand.Parameters.AddWithValue("#Complete", "False")
insertcommand.Parameters.AddWithValue("#Task", row.Cells(0).Value)
insertcommand.Parameters.AddWithValue("#Start_date", row.Cells(1).Value)
insertcommand.Parameters.AddWithValue("#Due_Date", row.Cells(2).Value)
insertcommand.Parameters.AddWithValue("#JRID", txtJRID.Text)
insertcommand.Parameters.AddWithValue("#Task_Manager", row.Cells(3).Value)
insertcommand.Parameters.AddWithValue("#Entered_By", GetUserName())
insertcommand.Parameters.AddWithValue("#Time_Entered", Now)
NextTask()
End If
Next
End With
conn.Open()
comm.ExecuteNonQuery()
End Using
End Using
I figured it out in case anyone is wondering, here is my new code:
Connexion.Open()
Dim query As String = String.Empty
Dim keypos = 0
query &= "UPDATE schedule SET Task = #Task, Complete = #Complete, Start_date = #Start_date, "
query &= "Due_date = #Due_date, JRID = #JRID, Task_Manager = #Task_Manager, Entered_By = #Entered_By, Time_Entered = #Time_Entered "
query &= "WHERE TaskID = #TaskID "
query &= "IF ##ROWCOUNT = 0 INSERT INTO schedule ( TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered)"
query &= " VALUES ( #TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered);"
For Each row As DataGridViewRow In MainSchedule.DataGridView1.Rows
If Not (row.Cells(0).Value = Nothing) Then
insertcommand.Parameters.Clear()
insertcommand.CommandText = query
insertcommand.Parameters.AddWithValue("#TaskID", row.Cells(0).Value)
insertcommand.Parameters.AddWithValue("#Complete", "False")
insertcommand.Parameters.AddWithValue("#Task", row.Cells(1).Value)
insertcommand.Parameters.AddWithValue("#Start_date", row.Cells(2).Value)
insertcommand.Parameters.AddWithValue("#Due_Date", row.Cells(3).Value)
insertcommand.Parameters.AddWithValue("#JRID", txtJRID.Text)
insertcommand.Parameters.AddWithValue("#Task_Manager", row.Cells(4).Value)
insertcommand.Parameters.AddWithValue("#Entered_By", GetUserName())
insertcommand.Parameters.AddWithValue("#Time_Entered", Now)
insertcommand.ExecuteNonQuery()
End If
keypos = keypos + 1
Next
Connexion.Close()

SQL statement to join tables - Nothing is working

This statement is extracting a list to excel which works fine
string sql = "select wo.email, wo.productid, wo.variantid ";
sql += "from woeosemails wo ";
sql += "order by email, productid ";
string attachment = "attachment; filename=EmailList.csv";
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("content-disposition", attachment);
HttpContext.Current.Response.ContentType = "text/csv";
HttpContext.Current.Response.AddHeader("Pragma", "public");
HttpContext.Current.Response.Write("email,productid,variantid");
HttpContext.Current.Response.Write(Environment.NewLine);
using (SqlConnection conn = new SqlConnection(DB.GetDBConn()))
{
conn.Open();
using (IDataReader NotifyReader = DB.GetRS(sql, conn))
{
while (NotifyReader.Read())
{
string email = DB.RSField(NotifyReader, "email");
int productid = DB.RSFieldInt(NotifyReader, "productid");
int variantid = DB.RSFieldInt(NotifyReader, "variantid");
email = email.Replace("\"","\"\"");
HttpContext.Current.Response.Write("\"" + email + "\"," + productid.ToString() + "," + variantid.ToString());
HttpContext.Current.Response.Write(Environment.NewLine);
}
}
conn.Close();
}
HttpContext.Current.Response.End();
I've tried adding a variety and I thought that this would work
I want to add two columns from another sql table, these are Name and SKU. Any ideas on how I can modify the first part of this code, I have tried joining the tables but nothing seems to work. The closest I have is modifying the first part to this
string sql = "select wo.email, wo.productid, wo.variantid, p.Name pname, p.Name psku, ";
sql += "from woeosemails wo ";
sql += "join Product p with (nolock) on p.ProductID = wo.productid ";
sql += "order by email, productid ";
Any help would be great
First of all you need to put alias to your order by properties and remove the comma at first line at the end. Try following:
string sql = "select wo.email, wo.productid, wo.variantid, p.Name pname, p.Name psku ";
sql += "from woeosemails wo ";
sql += "join Product p with (nolock) on p.ProductID = wo.productid ";
sql += "order by wo.email, wo.productid ";
The order by could be messing this up, you have two ProductID's, so you need to specify which one, ie: wo.productid. Check the same for email too.

SQL Server 2005 CE 3.5 Re seed IDENTITY

I have inserted some rows into a data table with
Set Identity_insert tblEvent on
I then attempt to 'reseed' the Identity field
int MaxId = this.MaxID()+1;
string upgrade = "ALTER TABLE " + Table + " ALTER COLUMN ID IDENTITY("+ MaxId.ToString() +",1)";
System.Data.SqlServerCe.SqlCeCommand cmd = new System.Data.SqlServerCe.SqlCeCommand(upgrade, connection);
cmd.CommandType = System.Data.CommandType.Text;
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
'MaxId' is determined by
int MaxId = 0;
string upgrade = "select Max(ID) from " + Table;
System.Data.SqlServerCe.SqlCeCommand cmd = new System.Data.SqlServerCe.SqlCeCommand(upgrade, connection);
cmd.CommandType = System.Data.CommandType.Text;
connection.Open();
MaxId = (int)cmd.ExecuteScalar();
connection.Close();
return MaxId;
However, if I query Max(ID) again after seeding it has'nt changed
Any idea's aprreciated
Try this:
string upgrade = " DBCC CHECKIDENT('[" + Table + "]', RESEED, " + (MaxId + 1)+ " )"
weird, could it be a permissions issue. you should have seen an exception though, unless the exception is gobbled up by a catch all.