I have some columns like text_en, text_es, text_de in a SQL table. Now I want to retrieve the value from just one column depending on the language.
So I created an sql string
SELECT #textfield FROM <table>
and in the vb code I use
cmd.AddWithValue("textfield", "text_" + lang)
But sql returns the name of the column instead of the value of that column. How can I get the value?
You can also do
SELECT CASE #textfield
WHEN 'text_en' THEN text_en
WHEN 'text_es' THEN text_es
WHEN 'text_de' THEN text_de
END AS local_text
FROM TableName
You can't use variables are column names in SQL, not like this, anyway.
You need to use dynamic SQL in order to specify column names like this.
I suggest reading The Curse and Blessings of Dynamic SQL for a comprehensive treatment of the subject.
Don't pass it as a parameter, pass it as a string literal. Your sql statement should be in the form:
string col1name = 'somename';
string sql = 'SELECT ' + col1name + ' FROM TableName';
But if you have a parameter passed to the WHERE clause you should pass it as a parameter like what you did in your question.
Note that: Your query, this way is vulnerable to SQL Injection. In your case, you can pass your concatenated SQL statement to a stored procedure then use sp_executesql, not EXEC().
Related
I'm writing an R Shiny/SQLite app. In the app, I have a function that returns a column from one of the tables in my SQLite database, with the function taking the table name as an input.
Before sending the query to SQLite, the function checks that the table name equals one of the table names that the user is allowed to access. However, I am not using a parameterized query, because the term I'm changing is not a variable used for comparison but the name of the table to extract information from. (There might be a way to make this work anyway with a parameterized search, I suppose.)
My question is whether this is safe from an SQL injection? Can the query be altered on its way from the server to the database, or only from an alteration in the ui input to the server?
(Bear with me, I am new to SQLite.)
Assuming your query is being concatenated as follows:
tbl <- "yourTable"
sql <- paste0("select * from ", tbl, " where some_col = 1")
Then there should be no chance of SQL injection, assuming you check the incoming table name and verify that it matches a table name in your whitelist. Note that this step is critical here to keeping things safe. Let's say that you didn't sterilize the incoming table name. Then, consider this:
tbl <- "yourTable; delete from yourTable"
This would result in the following query being submitted for execution:
select * from yourTable; delete from yourTable where some_col = 1;
Assuming your SQLite driver allows multiple SQL statements to execute, the above hack/trick might end up deleting data from a large portion of one of your tables.
So, your approach should be safe provided that you check the table name. Note that strictly speaking the table name itself is not a parameter in a parameterized query. Rather, only the literal values in the query are parameters.
SQL query parameters cannot be used in place of a table name anyway, so comparing the table name to a list of known authorized tables is your only option.
Yes, it is safe. If you're in control of the set of values that can be interpolated into the SQL query, then you can prevent unauthorized SQL injection.
Note that some other elements of SQL queries cannot be parameters:
Any identifier, e.g. a table name, column name, or schema name.
Expressions
Lists of values in an IN ( ... ) predicate. Use one parameter per value in the list.
SQL keywords.
A query parameter can be used only in place of a single scalar value. That is, where you would use a quoted string literal, quoted date literal, or numeric literal.
The problem of SQL injection is only the user input. Nothing happens to the query on its way from the server to the database (well a malware could in theory alter it, but then even a parametrized query wouldn't help).
I.e., if you create a SQL string like this (C#):
sql = "SELECT * FROM " + tableName;
Then a user might enter a tableName like
MyTable; DROP TABLE MyTable
Guess what happens.
So, if you check the table name, you are on the safe side.
I have done IN statement straight to SQL but I was trying to use it the objecdatasource. I have a textbox where users need query multiple item codes like this 1001,1002,1003 but how can I use this IN statement with a parameter with objectdatasource?
TIA
Just pass the textbox value of "1,2,3" to the parameter as a full string, and split the contents by "," within the object your passing the data to.
How to insert a string like this:
local Namestring="my mother's gift"
local insertQuery1 =[[INSERT INTO planne_tbl VALUES (']]..Namestring..[[');]]
db:exec( insertQuery1 )
How to insert ' symbol in sqlite.
Constructing SQL commands by concatenating strings will not only lead to formatting problems but will also allow SQL injection attacks.
The recommended way to use string values in SQL is to use parameters.
In Lua, it works like this:
local Namestring="my mother's gift"
local insertQuery1 = "INSERT INTO planne_tbl VALUES (?)"
local stmt = db:prepare(insertQuery1)
stmt:bind(1, Namestring)
stmt:step()
stmt:finalize()
(This is needlessly complex; you might want to write a helper function for this.)
In my programming task I've gone down a dark alley and wished I hadn't, but there is no turning back now.
I'm building up a SQL statement where the table name, column name and id value are retrieved from query string parameters i.e. ("SELECT [{0}] FROM [{1}] WHERE [Id] = {2};", c, t, id)
But it isn't as bad as it looks, I'm protected:
Only authenticated users (i.e. signed in users) can execute the Page_Load
I'm checking that both the table and the column exists beforehand
(using GetSchema etc.)
I'm checking that the Id is an integer beforehand
All my tables have Id columns
The database connection is reasonably secure
The field value is expected to be of type NVARCHAR(4000) or NVARCHAR(MAX) so I'm avoiding ExecuteScalar and I'm trying out LINQ ExecuteQuery because I like LINQ. But I'm a bit out of my depth again.
I've got this far:
Dim db As New MyDataContext
Dim result = db.ExecuteQuery(Of ITable)("SELECT [{0}] FROM [{1}] WHERE [Id] = {2};", c, t, id)
Is this the right way to go?
How do I get first row and first column value?
Is there a better alternative?
P.S. It's a SQL Server 2005 database
Any help appreciated.
Thanks.
SQL Server requires the tables ans columns to be statically known. You can't provide them using command parameters. You can't say
select * from #tableName
because the table name can't be a variable.
You need to build the SQL string with C# ensuring proper escaping of identifiers. Escaping works like this:
var escaped = "[" + rawUntrustedUserInput.Replace("]", "]]") + "]";
This is safe.
if i have a field in my table that i want to verify exists, how do i use the contains method to determine if it exists.
i would have thought the contains method just takes in a string but it seems to take in my whole linq data object
Contains is an extension method for IEnumerable that determines whether a given object is present in the enumerable. That's not what you want here.
I'm guessing that you have a LINQ query like this:
IEnumerable<string> productNames = from p in db.Products select p.ProductName;
And now you want to verify that the ProductName field actually exists to avoid run-time errors. There is actually no need to check that. Try replacing p.ProductName by a field that doesn't exist. The compiler will complain.
Of course, this assumes that the actual database schema matches the one used to generate the database class with MSLinqToSQLGenerator.
Not sure how to do it with LINQ but you could do:
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE _NAME ='MyTable' and COLUMN _NAME='MyColumn'
then based on the count returned from the query you will know if the column exists or not.