Avoiding reference to schema in queries in postgresql - c#

Being new to C# and postgresql, but not to development and DBs, I'm trying to make the connection from C# .NET to postgresql. I keep running into the same syntax error.
In postgresql I have created a table "Test" with one column "Text".
To insert data into the table, in pgAdmin 4, I use:
insert into public."Test" ("Text") values('It Works!')
This works.
Now I try this in C# where I have a working connection to the database:
1 NpgsqlCommand cmd = new NpgsqlCommand("insert into Test ("Text") values('It Works!')", postconn);
2 cmd.ExecuteNonQuery();
This gives me a compilation error. Apparently from all the double quotes.
If I change the command text to:
"insert into Test ('Text') values('It Works!')"
with single quotes around Text the compiler is happy, but Npgsql gives me a syntax error.
Questions:
In pqsql:
I can see from google that it's possible to get around use the double quotes and the schema reference in psql.
But what does it take?
In C#:
Is there a way to construct the string, so that the compiler will accept it?
pgAdmin 4 is version 1.0
PostgreSQL is version 9.6
C# I believe is the most recent version.

In addition to the comment about escaping your quotes, you really should use parameters instead of literals. It may seem like more work initially, but it's:
Safer (SQL-injection proof)
Easier on the database -- supports compile once, execute many
Avoids having crazy SQL statements within C# that have concacts or string.format all over the place
Avoids the need to single quote literal values and omit quotes for numbers, booleans
Strong datatyping means no formatting (dates, for example)
Here is your code with parameters:
NpgsqlCommand cmd = new NpgsqlCommand("insert into Test (\"Text\") " +
" values(:TEST)", postconn);
cmd.Parameters.AddWithValue("TEST", "It Works");
cmd.ExecuteNonQuery();
Seems like I made your life harder, but your example was a trivial one. As you move to complex SQL statements with multiple parameters and different datatypes, you will see the true value.
On a final rant, while there is nothing technically wrong with making case-sensitive field names, it sure does cause nothing but headaches. Yours is a perfect example. Without the double quotes around the field "Test", you wouldn't have had an issue to begin with.

Related

How to pass list of guid as a parameter to a sql command

I need to filter a sql request by passing a list of id to , this is the command:
var command = "select Software.Name as SoftwareName,SoftwareType.Name as SoftwareType from AssetManagement.Asset as Software inner join AssetManagement.AssetType as SoftwareType on (SoftwareType.Id = Software.TypeId) where Software.Id in (#P)";
cmd.Parameters.AddWithValue("#P", authorizedSoftwaresId);
authorizedSoftwaresId is a list of string , containing data like :
"7D23968B-9005-47A9-9C37-0573629EECF9,F1982165-3F6D-4F35-A6AB-05FA116BA279"
with that it returns to me just one row, I tried adding quotes foreach value but i got "converstion from string caractere to uniqueidentifier failed " exception
This is a pretty common problem and the answer might depend on your database engine and whether you're using ADO.Net, Dapper, etc.
I'll give you some hints from my own experience with this problem on both MS Sql Server and PostgreSQL.
A lot of people think AddWithValue is a devil. You might consider Add instead.
The IN (#P) in your SQL statement might be the source of your problem. Try the Any option instead. See Difference between IN and ANY operators in SQL ; I've had success with this change in similar situations.
If all of your inputs are GUIDs, you might consider changing the type to a collection of GUIDs, although I don't think this is the fix, you have to try everything when you're stuck.
If you have to, you can parse the string version of your collection and add the ticks (') around each value. This choice has consequences, like it may prevent you from using a parameter (#P), and instead construct the final SQL statement you desire (i.e., manually construct the entire WHERE clause through string manipulations and lose the parameter.)
Good luck.

Cant insert character values from textbox to database

Trying to Insert into database from textboxes, but it will only accept integers and not characters - what could the problem be?
string sCMD = string.Format("INSERT INTO [Table] ([Item], [Des1],[Des2], [Prodline], [ANR], [STime]) VALUES({0},{1},'0',{2},{3},{4})"
,txtText1.Text, txtText2.Text, txText3.Text, txtText4.Text, txtText5.Text);
The name "" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
Here's something to consider:
using (SqlConnection c = new SqlConnection(connString))
{
c.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO [Table] ([Item], [Des1],[Des2], [Prodline], [ANR], [STime]) VALUES(#Item,#Des1,'0',#ProdLine,#ANR,#STime)", c))
{
cmd.Parameters.AddWithValue("#Item", txtText1.Text);
cmd.Parameters.AddWithValue("#Des1", txtText2.Text);
cmd.Parameters.AddWithValue("#ProdLine", txText3.Text);
cmd.Parameters.AddWithValue("#ANR", txtText4.Text);
cmd.Parameters.AddWithValue("#STime", txtText5.Text);
cmd.ExecuteNonQuery();
}
}
If you were to send the SQL statement you're building to the server it might look something like this:
INSERT INTO [Table] ([Item], [Des1],[Des2], [Prodline], [ANR], [STime])
VALUES(Item Name,Here is my description.,'0',Prod line,ANR value,some time)
Clearly that's going to fail. It's not even surrounding the values with single quotes. Now, all of them may not be character, I get that, but you get my point.
But to add insult to injury it's wide open to SQL Injection the way you have it written. With the parameterized approach it's not.
This is a very dangerous line of code.
For starters, you are creating a string with no delimiters whatsoever for the values, which means that the only values that could pass withour issue are integers. Anything else needs to be delimited, which you don't do in this String.Format statement.
Worse, you are trying to create a sql statement from direct user input. Any weird value can cause your code to fail, or worse, cause execution of unwanted code. Imagine what would happen in a user entered eg 'sdf','sdfs',sdf' as the FIRST value. The resulting string would have 3 correct values for the first three columns that came from the first textboxt.
Now image what would happen if the user entered something like 'blablabla';DROP TABLE sometable;--. This would cause the Delete command to execute. This is a standard SQL injection attack scenario.
There are many more problems, eg when you try to pass numbers with floats, dates or any type whose conversion to string depends on your locale.
Instead of trying to construct a SQL query by string concatenation, you should use parameterized queries, as described in Give me parameterized SQL or give me death. The resulting code is easier to write, performs much faster, has no conversion errors and is not subject to SQL injection attacks,

Why do we need SqlCeCommand.Parameters.AddWithValue() to Insert a value?

I have a C# WPF desktop application which uses SQL Compact 3.5 as its embedded database.
In the insertion function it has
using (SqlCeCommand com = new SqlCeCommand(
"INSERT INTO FooTable VALUES(#num)", con))
{
com.Parameters.AddWithValue("#num", num);
com.ExecuteNonQuery();
}
I don't get what the com.Parameters.AddWithValue() is about. I commented out this line of code and the insertion function run exactly the same. I thought ExecuteNonQuery carries out the insertion, so what is this Parameters.AddWithValue thing?
#num is a TSQL parameter. Without AddWithValue(#num, num) this is neither defined nor assigned a value. It simply will not work with the parameter omitted, and even if it did: where would it get your chosen value (num) from? The absolute best it could do would be to use null which was not your intent; more typically it would simply fail to execute (are you sure you aren't swallowing an exception somewhere?).
Note that concatenating the value into the string itself is not recommended; it would cause a SQL injection risk, and can reduce performance (plan re-use; not sure this applies to CE though - CE might very well not bother with cached plans).

Replace ' with \' in all textboxes in my program

So throughout my program I have probably 50 or so text boxes in various places. I know how to replace a single quote with something (in this case ' -> \'), but I am thinking there must be a better way to do this than go through and add specific code for every single text box. I have to do this because when this stuff is getting sent to the database, if there is a single quote, it gives an error. Is there a way to change the default TextBox control behavior so that all textboxes in the program automatically replace all single quotes with \'?
EDIT:
string statement = "select count(*) from users where username='#username'";
MySqlCommand command = new MySqlCommand(statement, conn);
command.Parameters.AddWithValue("#username", username);
if (Convert.ToInt32(command.ExecuteScalar()) == 1)
I have been playing with the paramerterized code and this is what I have right now. From how I understand it, the statement string is basically the same as before, but where I used to have the variable "username" I know use a parameter (which I called #username), then the command is created. Then in the parameters.addwithvalue, it replaces the parameter username, with whatever is in the variable username. Unfortunately, this is not working for me, and I don't really see how it helps because username is still just getting stuck in the command?
EDIT: Found the problem, in the statement you don't need to put single quotes around '#username'
so it should be:
string statement = "select count(*) from users where username=#username";
Don't use concatenation to build SQL queries. Use proper parametrized queries. This will make repeated queries a bit faster and will also eliminate input sanitizing code (replacing ' with \' for example) and SQL injection attacks.
You should be using parameterized queries, not only to resolve the problem you have, but also to reduce your exposure to SQL injection. When you use string concatenation to build SQL queries you are suseptable to SQL injection attackes.
U can use onKeyUp javascript function or asp.net OnTextChanged event to create function that will change quotes.

SQLite issues, escaping certain characters

I'm working on my first database application. It is a WinForms application written in C# using a SQLite database.
I've come across some problems, when a apostrophe is used, my SQLite query fails. Here is the structure of my queries.
string SQL = "UPDATE SUBCONTRACTOR SET JobSite = NULL WHERE JobSite = '" + jobSite + "'";
For instance, if an apostrophe is used in the jobSite var, it offsets the other apostrophes in the command, and fails.
So my questions are:
1. How do I escape characters like the apostrophe and semicolon in the above query example?
2. What characters do I need to escape? I know I should escape the apostrophe, what else is dangerous?
Thanks for your help!
Rather use Parameters
There is a previous stack-overflow question about it
Adding parameters in SQLite with C#
if you need more functionality you can also use Entity Framework
http://sqlite.phxsoftware.com/
Sorry not to familiar with the Syntax but the concept should same.
Something like :
SQLiteCommand Command = "UPDATE SUBCONTRACTOR SET JobSite = NULL WHERE JobSite = #JobSite";
Command.Parameters.Add(new SQLiteParameter("#JobSite", JobSiteVariable));
command.ExecuteNonQuery();
to escape an apostrophe add another apostrophe...
so a string like it's should be inserted as it''s
You may also need to escape quotation marks. The way to do this is to use a backslash as an escape charater...
like so... 'and he said\"escape all those quotes\"'
You should also beware of SQL injections... depending on the type of programming language you are using there exist different functions that can help clean out any malicious code.
C# tutorial on SQL Injections for example
You should never concatenate strings to build SQL queries for SQLite - or for any other SQL DB if possible. It makes your code fragile and opens up potential entry points for injection attacks.
The proper way to do it is to use hosted parameters. This approach removes the need for cumbersome string filtering. I am not sure how to do that in C# for SQLite but any decent language binding for SQLite should allow you to use hosted parameters.

Categories

Resources