Not able to prepare NpgsqlCommand? - c#

I am currently trying to make a prepared command, but for some reason am I getting this error
Hint "There is a column named \"entity_id\" in table \"temp_country\", but it cannot be referenced from this part of the query." string
when I do this
connection.Execute(#$"DROP TABLE IF EXISTS temp_{entityName}; select * into temp_{entityName} from {entityName}");
var getNewIdSql =
$"INSERT INTO \"temp_{entityName}\"(entity_id) values(#entity_id) RETURNING entity_id";
NpgsqlCommand insertEntry = new NpgsqlCommand(getNewIdSql, connection, transaction);
insertEntry.Prepare();
and I am ont sure what I am doing wrong here? because table exist, and has the column? so I am not sure why this is going wrong.

The error message is indeed misleading, but the problem is simply that you haven't added an NpgsqlParameter for entity_id to the NpgsqlCommand before calling Prepare:
NpgsqlCommand insertEntry = new NpgsqlCommand(getNewIdSql, connection);
var param = new NpgsqlParameter("entity_id", NpgsqlDbType.Integer);
insertEntry.Parameters.Add(param);
insertEntry.Prepare();

Related

Conversion failed when converting from string to uniqueidentifier - loading DataTable with ExecuteReader

In attempting to do a SQL query (which returns one string and one uniqueidentifier to columns 0 and 1 respectively) I get "Conversion failed when converting from a character string to uniqueidentifier" in my exceptions log. How can I avoid this? I'm assuming the issue is, the datatables columns are not defined, so it's expecting a string and SQL is trying to convert it. The exception is logged. Surprisingly to me the GUID is stored successfully to da[1]. So my program technically works, however I want to clear this exception and to do that I need to understand why it's happening and how to go about fixing it.
da = new DataTable();
da.Clear();
...
string invoiceStatusSQL = #"select status,invoice_id from invoices where acct_id='" + accountid + "'";
command = new SqlCommand(invoiceStatusSQL, cnn);
da.Load(command.ExecuteReader());
You should always parameterise your SQL queries to help prevent SQL injection and avoid problems like you're facing now. See Why do we always prefer using parameters in SQL statements?.
Use SqlParameter to add the parameters to the SqlCommand.
string invoiceStatusSQL = #"select status, invoice_id from invoices where acct_id = #accountId";
command = new SqlCommand(invoiceStatusSQL, cnn);
SqlParameter idParam = new SqlParameter("#accountId", accountid);
command.Parameters.Add(idParam);
da.Load(command.ExecuteReader());
You can also specify the actual database type when creating the parameter, which will reduce any issues you might have with the framework inferring the type incorrectly (although I don't think that would happen in your case for a Guid/UniqueIdentifier). One way to specify the type is shown below.
var p = new SqlParameter
{
ParameterName = "#accountId",
SqlDbType = SqlDbType.UniqueIdentifier,
Value = accountid
};

System.Data.SqlClient.SqlException: 'Incorrect syntax near ','.'

I have created this code to add new records to the database however, every time I rum the code I get this error:
System.Data.SqlClient.SqlException: 'Incorrect syntax near ','.'
And I have no idea how to fix this error, I have looked online and tried different ways to fix it and none of them helped or fixed the problem.
The code is found below:
SqlCommand sdk = new SqlCommand("SELECT ([Id],[Title],[JobInfo],[DateSet],[DateDue],[WhoFor]) FROM Information_Schema.Columns FROM JobInformation", ConnectToDatabase);
ConnectToDatabase.Open();
SqlDataReader reader;
reader = sdk.ExecuteReader();
ConnectToDatabase.Close();
I believe it to be the first line of code, but I have no clue where the error could be within it.
I expect you mean something like:
ConnectToDatabase.Open();
using(var sdk = new SqlCommand(
"SELECT [Id],[Title],[JobInfo],[DateSet],[DateDue],[WhoFor] FROM JobInformation",
ConnectToDatabase))
using(var reader = sdk.ExecuteReader())
{
while(reader.Read()) { /* process row */
}
ConnectToDatabase.Close();
However, you may find it easier to use a tool like dapper:
var jobs = ConnectToDatabase.Query<JobInfo>(
"SELECT [Id],[Title],[JobInfo],[DateSet],[DateDue],[WhoFor] FROM JobInformation"
).AsList();
(which does everything including the open/close, and populates the columns into your own JobInfo type that you need to create)
However, you say:
I have created this code to add new records to the database
in which case you'll need to use insert, not select - and the ExecuteNonQuery method of SqlCommand (or the Execute method of "dapper").
For an insert:
using(var cmd = new SqlCommand(#"
insert JobInformation(Title, JobInfo, DateSet, DateDue, WhoFor)
values (#title, #jobInfo, #dateSet, #dateDue, #whoFor)", ConnectToDatabase))
{
cmd.Parameters.AddWithValue("#title", title);
cmd.Parameters.AddWithValue("#jobInfo", jobInfo);
cmd.Parameters.AddWithValue("#dateSet", dateSet);
cmd.Parameters.AddWithValue("#dateDue", dateDue);
cmd.Parameters.AddWithValue("#whoFor", whoFor);
cmd.ExecuteNonQuery();
}
or with dapper:
ConnectToDatabase.Execute(#"
insert JobInformation(Title, JobInfo, DateSet, DateDue, WhoFor)
values (#title, #jobInfo, #dateSet, #dateDue, #whoFor)",
new { title, jobInfo, dateSet, dateDue, whoFor});

System.Data.SqlClient.SqlException occured in System.Data.dll (incorrect syntax)

I can't work out what the problem is here, since the additional information comes back as: Incorrect Syntax near '('. I think I need fresh eyes on this I can't see the error.
Here is my code, im trying to update the information to the selected Owner_ID.
System.Data.SqlClient.SqlCommand command = new SqlCommand("UPDATE OwnerTable SET (Owner_ID, Owner_Fname, Owner_Lname, Owner_HouseNo, Owner_Street, Owner_County, Owner_PostCode, Owner_Tele, Owner_Email) VALUES (#OwnerID, #OwnerFName, #OwnerLName, #OwnerHouseNo, #OwnerStreet, #OwnerCounty, #OwnerPostCode, #OwnerTele, #OwnerEmail) WHERE Owner_ID = #OwnerID", connection);
command.CommandType = CommandType.Text;
command.Connection = connection;
command.Parameters.AddWithValue("#OwnerID", CB_OWNER_ID.GetItemText(CB_OWNER_ID.SelectedItem));
command.Parameters.AddWithValue("#OwnerFName", TXT_OWNER_FNAME.Text);
command.Parameters.AddWithValue("#OwnerLName", TXT_OWNER_LNAME.Text);
command.Parameters.AddWithValue("#OwnerHouseNo", TXT_OWNER_HOUSENO.Text);
command.Parameters.AddWithValue("#OwnerStreet", TXT_OWNER_STREET.Text);
command.Parameters.AddWithValue("#OwnerCounty", TXT_OWNER_COUNTY.Text);
command.Parameters.AddWithValue("#OwnerPostCode", TXT_OWNER_POSTCODE.Text);
command.Parameters.AddWithValue("#OwnerTele", TXT_OWNER_TELE.Text);
command.Parameters.AddWithValue("#OwnerEmail", TXT_OWNER_EMAIL.Text);
You used INSERT syntax instead of UPDATE syntax:
UPDATE OwnerTable SET Owner_ID = #OwnerID, Owner_Fname = #OwnerFName ..etc
Or if you indeed wanted to insert a new record change UPDATE to INSERT INTO and remove the WHERE (but I guess the WHERE indicates that you wanted to update).
Btw: are you sure to update the OwnerID in the OwnerTable? Seems wrong to me.

C# ComboBox Select Error: "Incorrect Syntax Near '.'"

Note: my office doesn't allow me to view YouTube and several other sites that probably have the answer to this question on them (they are blocked), which is why Googling the answer hasn't yielded results.
ComboBox code reference: found here
On my C# Form, I have filled a ComboBox with tables from a database (see below code), which returns the appropriate values and functions correctly:
public Form1()
{
InitializeComponent();
// Connection
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "CONNECTION STRING" // shortened for security and convenience
// Fill ComboBox with SQL Values
conn.Open();
SqlCommand cmbTables = new SqlCommand("SELECT name FROM sys.tables", conn);
SqlDataReader read = cmbTables.ExecuteReader();
DataTable cmbData = new DataTable();
cmbData.Columns.Add("name", typeof(string));
cmbData.Load(read);
cmb1.DisplayMember = "name";
cmb1.DataSource = cmbData;
conn.Close();
}
After the ComboBox loads the tables (which works), the application then selects a table and clicks a button that loads the table, which is selected. This is where the code errors:
private void button1_Click(object sender, EventArgs e)
{
using (var connection = Utilities.GetConnection())
{
string table = Convert.ToString(txt1.Text);
string cmb1Value = Convert.ToString(cmb1.SelectedItem);
// Stored Procedure
SqlCommand select = new SqlCommand("EXECUTE STOREDPROCEDURE" + cmb1Value, connection); // shortened for security and convenience
select.Parameters.Add(new SqlParameter(cmb1Value, table));
// Data View
SqlDataAdapter ad= new SqlDataAdapter(select);
ad.SelectCommand = select;
DataTable dt = new DataTable();
ad.Fill(dt); // this generates the error "Incorrect Syntax Near '.'"
BindingSource b = new BindingSource();
b.DataSource = dt;
dGrid.DataSource = b;
ad.Update(dt);
connection.Close();
}
}
Even though the ComboBox loads the appropriate values, from the above code, I may be missing something which attaches those values to the SELECT stored procedure (all it does is call SELECT statement through a variable passed to it). The error, "Incorrect Syntax Near '.'" looks like a SQL Server error that I've seen, but can't remember how I generate it (this is how I usually troubeshoot where the TSQL code went wrong).\
Stored Procedure Related code:
C#:
SqlCommand select = new SqlCommand("EXECUTE STOREDPROCEDURE " + cmb1Value, connection);
TSQL:
CREATE PROCEDURE [STOREDPROCEDURE]
#TableName VARCHAR(250)
AS
BEGIN
DECLARE #sql NVARCHAR(MAX)
SET #sql = N'SELECT TOP 100 *
FROM ' + #TableName
EXECUTE(#sql)
END
-- Note this works in SSMS without a problem.
The above code is incorrect, and when I tweak the TSQL code, I generate similar errors, telling me that somewhere I am missing a conversion, or another variable because SQL Server isn't seeing these table values returned by the SELECT (first block of code). I can ascertain this because I have a second ComboBox that uses similar code EXCEPT that I populated the ComboBox with manual values, and it connects to the tables in the database with no error. So, the ComboBox, which grabs values from the database, that you see above, does not function correctly.
For instance, if I only add the below line of code to the code, I receive an error that it can't find the database "EXECUTE STOREDPROCEDURE System'
select.CommandType = CommandType.StoredProcedure;
However, System isn't a part of anything, so where did that come from? It never errored with this code on the manual ComboBox, as it had no trouble finding the database (using the same connection string, server and database!).
If I try to use a TSQL parameter, such as:
SqlCommand select = new SqlCommand("EXECUTE stp_ReturnTable #p", scon);
select.Parameters.Add(new SqlParameter("#p", cmb1Value));
Suddenly, it can't find the stored procedure. Again, the connection strings are identical for the manual ComboBox and the dynamic ComboBox.
I think the code behind the dynamic ComboBox is wrong. When I'm out of the office, I'll review some videos with detailed demonstrations on how to create a dynamic ComboBox from a database and I have a hunch that a system object is in the way (based on the System error, which exists nowhere in my code, as well as it suddenly being unable to find the database or procedure).
The missing key point in your code is the CommandType.
Without the proper set of this property the default is CommandText and thus the Framework expects a statement that starts with SELECT/INSERT/UPDATE/DELETE etc....
using (var connection = Utilities.GetConnection())
{
string table = Convert.ToString(txt1.Text);
string cmb1Value = Convert.ToString(cmb1.SelectedItem);
// Stored Procedure
SqlCommand select = new SqlCommand("STOREDPROCEDURE", connection);
select.Parameters.Add(new SqlParameter("#TableName", cmb1Value));
// That's the key to let ADO.NET accept the previous CommandText as valid.
// If you omit this the CommandText is assumed to be a SELECT/UPDATE/DELETE etc..
select.CommandType = CommandType.StoredProcedure;
// Data View
SqlDataAdapter ad= new SqlDataAdapter(select);
DataTable dt = new DataTable();
ad.Fill(dt);
BindingSource b = new BindingSource();
b.DataSource = dt;
dGrid.DataSource = b;
}
EDIT Having seen the code of the SP then you could simply set the SqlParameter name to the constant #TableName and pass the value extracted from the combobox as the value to be used inside the SP
EDIT I have looked again at your code and I suspect that the culprit is the line
string cmb1Value = Convert.ToString(cmb1.SelectedItem);
Looking at how you have filled your combo, this line, doesn't return the tablename as you expect, but the generic string System.Data.DataRowView because the DataSource of the combo is a DataTable and not a string collection. You should try to change that line in this way
DataRowView rw = cmb1.SelectedItem as DataRowView;
if(rw != null)
{
string cmbValue1 = rw["name"].ToString();
....
And yes, your code should work also without the CommandType.StoredProcedure line because the text EXECUTE sp param is recognized as a valid sql commandtext (but why do you use it when a direct call to the storedprocedure could be optimized for reuse?)

How to insert a file to an Image datatype in SQL Server 2005

I am trying to save a file to an Image datatype using inline query.
INSERT INTO tblPDFInfo(FileImage, PdfFileName, FeedDateTime, HasProcessed)
VALUES(#fileBytes, #fileName, getutcdate(), 0)
and then if I use string.format then it is rendering the byte array to string and so it serves no luck.
Another way if I create a sqlcommand and
objCmd = new SqlCommand(strSQL, objConn, objTrans);
objFileDataParam = new SqlParameter("#fileBytes", SqlDbType.Image);
objFileDataParam.Value = (byte[])fileData;
objCmd.Parameters.Add(objFileDataParam);
objFileNameParam = new SqlParameter("#fileName", SqlDbType.VarChar);
objFileNameParam.Value = PDFfileName;
objCmd.Parameters.Add(objFileNameParam);
objCmd.CommandText = strSQL;
Then when firing the query it is saying
System.Data.SqlClient.SqlException: Must declare the scalar variable
"#fileBytes"
And if in inline query I am declaring the same variable then it too gives me error saying
System.Data.SqlClient.SqlException: The variable name '#fileBytes'
has already been declared. Variable names must be unique within a
query batch or stored procedure.
How could I correct this up to make it working. Well I am not bound to a specific datatype but I need to save the file and later on retrieve it too, I think the image datatype would be a good choice, but could not make it happen. Any suggestions would be really helping.
Try this,
string strSql="INSERT INTO tblPDFInfo (FileImage,PdfFileName,FeedDateTime,HasProcessed)
values(#fileBytes,#fileName,#getutcdate,#hasprocessed)";
byte []bytes=(byte[])fileData;
objCmd = new SqlCommand(strSQL, objConn, objTrans);
objCmd.Parameters.Add("#fileBytes", SqlDbType.Image,bytes.Length).Value=bytes;
objCmd.Parameters.Add("#fileName", SqlDbType.VarChar,100).Value=PDFfileName;
objCmd.Parameters.Add("#getutcdate", SqlDbType.DateTime).Value=DateTime.Now;
objCmd.Parameters.Add("#hasprocessed", SqlDbType.Bit).Value=0;
objCmd.ExecuteNonQuery();

Categories

Resources