Here is a sqlite library problem (using C)
After binding parameters of a prepared statement, how can I print the SQL with the bound parameters for debugging?
I google it and only find a function to print the original prepare statement.
You can't access the prepared statement after the bind(). For debug-purposes, you can sprintf the values into the sql-string and give that to prepare() thus omitting the bind-calls.
What is your original sql string and what are your bind-calls?
Related
I have an Execute SQL Task which tries to execute a stored procedure, like this:
EXEC usp_stored_proc ?, ?, ? OUTPUT, ? OUTPUT;
I have 4 variables mapped to parameters. Ignoring the output parameters, these are both strings mapped to NVARCHAR params (as expected by the stored procedure).
When I run the package, an error tells me that execution failed with the message input string is not in the correct format. However, when I use a breakpoint to find the runtime values of the input parameters (or at least the variables mapped to them) and execute the same line of SQL in SSMS using the runtime values, it works fine.
Can anyone help? I'm at the end of my tether with this. I can't even find out the exact parameter causing the issue although it's probably both as the values follow the same format.
More details:
Connection type: OLE DB
Input Variable: String = schema.table
Mapped Param: NVARCHAR, ParamName = 0, ParamSize = -1
UPDATE
Solved the issue by making a new execute sql component that calls a stripped down procedure. I then slowly added lines of code to the procedure and additional parameters until arriving at the same component I started with and now it works. Comparing the original and rebuilt tasks, I see absolutely no differences (same with the procedure), so I don't know why this issue was occuring.
Try changing the parameter size (ParamSize) to match the parameter size within the stored procedure; if nvarchar(50) then set it to 50.
Solved the issue by making a new execute sql component that calls a stripped down procedure. I then slowly added lines of code to the procedure and additional parameters until arriving at the same component I started with and now it works. Comparing the original and rebuilt tasks, I see absolutely no differences (same with the procedure), so I don't know why this issue was occurring.
I’m experiencing a frustrating issue when trying to call a proc in an OLE DB source task. I’m using the SQL command from variable data access mode but I can see that it isn’t evaluating my variable correctly.
My variable (with ValidateAsExpression set to True) uses an expression to create a sql command like “EXEC ProcName ‘Param'” where the value of Param comes from a variable who’s value I set using an EXEC SQL task. Below is the expression:
“EXEC ProcName ” + “‘” + #[User::vDateThreshold] + “‘”
If I use a variable in my source that references a static value it works fine, but the issue seems to be when I use a variable which reference another variable in its expression.
Has anyone else come across this issue?
I’m using this method because I’ve had a similar issue when trying to use a parameter with the sql command data access method.
Thanks in advance
I’m using this method because I’ve had a similar issue when trying to use a parameter with the sql command data access method.
The right way to do that is by using SQL Command with parameters:
EXEC ProcName ?
And select #[User::vDateThreshold] as parameter.
Parameterized OLEDB source query
If it is not working then check your procedure code and make sure it generate a specific result set. If the result set is dynamic and columns are not fixed then you have to define it in the query using WITH RESULTSETS keyword.
https://www.mssqltips.com/sqlservertip/2356/overview-of-with-result-sets-feature-of-sql-server-2012/
From the name of #[User::vDateThreshold it seems like an SSIS datetime variable. Try setting this to a variable with an explicit cast and then executing the stored procedure with the variable. Make sure there that are single quotes (') within the CAST function as you would use if this was done in SSMS. When concatenating a datetime variable within a string variable in SSIS, the datetime variable must be converted to text, which is done with (DT_STR, length, codepage) in the sample expression below. I'm not sure what version you're using, but testing this out on SSDT for Visual 2017 worked fine for me. This will cover if you still want to hold the SQL in a variable, however the solution that #Hadi posted is a good option if you'd prefer to go that route.
"DECLARE #pDate DATETIME
SET #pDate = CAST('" + (DT_STR, 50, 1252)#[User::vDateThreshold] + "' AS DATETIME)
EXEC ProcName #pDate"
Thank you for the responses to my question.
I actually found the issue was with the ordering of my tasks in the package. When I looked closer at the values assigned to the relevant variables by using a break point on my exec SQL task I could see the wrong date was being passed to my proc. When I set the value of vDateThreshold at an earlier point the correct date value was assigned.
I think this was a case of looking at something for long enough that I was missing the obvious.
I am trying to build a scenario that would allow me to expose additional data from a server (for case-demo purposes). The server calls a vulnerable SQL code:
EXEC my_storeProc '12345'
where "12345" (not the single quotes) is the parameter. This performs a SELECT statement. I would like to eliminate this execution and instead call my own select statement, however the server side code will only accept the first select statement called, contained within the aforementioned EXEC call. Calling the second statement is easy:
EXEC my_storeProc '12345 ' select * from MySecondTable--
(the -- at the end will block the closing single quote added by the server to prevent errors). My problem is that although there are 2 select statements, the server will only parse the first one. Is there a way to cancel the first EXEC call without throwing an error so that the second one would be taken instead? Perhaps even a UNION but there isn't much I can do with only one variable open to exploit (variable being 12345 in this case).
You have to think of how it will be executed, specifically you want it called so it doesn't raise an exception and put the kabosh on the whole statement. You can't set the result to always true with a proc call, so there is no real way escape the proc. Instead, you'll want to slip a second command in, Your desired code looks like;
exec my_Storeproc '1234'; select * from mysecondtable
So we need to close the quotes, and make a new statement. That would mean the string with the insert needs to be;
1234'; select * from mysecondtable where 1 = '1
There is a flaw in this, whatever command you are executing is not being returned to the UI. To get the data you'll have to add a server connection to the second command.
To make the second command unnecessary you would have to inject code into the proc, which is a non starter since the proc is already complied and sql injection relies on confusing the compiler as to what is data and what is commands. For a more verbose explanation of that check out this answer:
https://security.stackexchange.com/a/25710
I've run in to a problem with a software I'm configuring. I do not have access to the source code, only the config.
The issue is as follows, in the configuration the software expects me to enter a string, but I would like the string to jump out of the compare and instead execute a funtion.
Using sql profiler I get something like this:
exec sp_executesql N'SELECT * FROM dummyTable WHERE (Name LIKE #Pattern)',N'
This does not work in my setup, because pattern is not clearly defind in advanced. I need to take the
variable passed as pattern and run it trough a sql function but I can't figure out how. Typically Pattern contains a single char, in my example "1". I've tried altering the Pattern to use an escape char and run my function on it, but I think I'm missing someting (If this is at all possible).
The variable I've send from config is as follows:
{0}' or Name like dbo.RunCalulation({0})
Giving me the following:
'…#Pattern nvarchar(43)',#Pattern=N'1'' or Name like dbo.RunCalulation(1) '
This executes, but does not give any response, so I think the esacpe char does not work, and it compares the whole string to Name.
I'm real stuck at this, hope someone has a good idea what to do (I know that not having the source code is a real problem here.
One of the huge advantages of query parameters (such as #Pattern) is that they help protect against SQL injection (which is what you are trying to do).
So the answer is that you cannot do what you want. There's no way to escape the #Pattern parameter and add some of your own SQL to that query, because everything you pass as #Pattern will be interpreted as data, and never as SQL command text (which is the reason why your SQL text ends up inside the single quotes, and why your quote is automatically escaped to ''.).
It's impossible to sqlite3_bind_text a table name because sqlite3_prepare_v2 fails to prepare a statement such as:
SELECT * FROM ? ;
I presume the table name is needed to parse the statement, so the quoting needs to have happened before sqlite3_prepare_v2.
Is there something like a sqlite3_quote_tablename? Maybe it already exists under a name I can't recognize, but I can't find anything in the functions list.
SQLite will escape identifiers for you with the %w format in the https://www.sqlite.org/printf.html family of functions.
your proposed sqlite3_quote_tablename function could sanitize the input to prevent sql injection attacks. To do this it could parse the input to make sure it is a string literal. http://sqlite.org/lang_expr.html#litvalue
If a table name has invalid characters in it you can enclose the table name in double quotes, like this.
sqlite> create table "test table" (id);
sqlite> insert into "test table" values (1);
sqlite> select * from "test table";
id
----------
1
Of course you should avoid using invalid characters whenever possible. It complicates development and is almost always unnecessary (IMO the only time it is necessary is when you inherit a project that is already done this way and it's too big to change).
When using SQLite prepared statements with parameters the parameter: "specifies a placeholder in the expression for a literal value that is filled in at runtime"
Before executing any SQL statement, SQLite "compiles" the SQL string into a series of opcodes that are executed by an internal Virtual Machine. The table names and column names upon which the SQL statement operates are a necessary part of the compilation process.
You can use parameters to bind "values" to prepared statements like this:
SELECT * FROM FOO WHERE name=?;
And then call sqlite3_bind_text() to bind the string gavinbeatty to the already compiled statement. However, this architecture means that you cannot use parameters like this:
SELECT * FROM ? WHERE name=?; // Can't bind table name as a parameter
SELECT * FROM FOO WHERE ?=10; // Can't bind column name as a parameter
If SQLite doesn't accept table names as parameters, I don't think there is a solution for your problem...
Take into account that:
Parameters that are not assigned values using sqlite3_bind() are treated as NULL.
so in the case of your query, the table name would be NULL which of course is invalid.
I was looking for something like this too and couldn't find it either. In my case, the expected table names were always among a fixed set of tables (so those were easy to validate). The field names on the other hand weren't so I ended up filtering the string, pretty much removing everything that was not a letter, number, or underscore (I knew my fields would fit this parameters). That did the trick.