How do I get the output from the sql_query?
import pyodbc
sql_query = "print 'Hello World'"
conn = pyodbc.connect("DRIVER={SQL Server};
SERVER=myserver;
DATABASE=mydatabase;
UID=myusername;
PWD=mypassword")
cur = conn.cursor()
cur.execute(sql_query)
cur.commit()
for row in cursor.fetchall():
print row
So far I think an SQL print is out of band from the usual structured responses?
http://www.easysoft.com/developer/languages/perl/sql_server_unix_tutorial.html#print_statement_status_messages has something similar to what I'm trying to do in Perl.
The closest I can see is the optional:
http://www.python.org/dev/peps/pep-0249/#cursor-messages So I guess it's just not implemented?
When running the query PRINT 'Hello World' the output is being returned as console output (string), and fetchall is reviewing the result set (object) from a query. RAISERROR is an error condition, and can stop the process. I'm not saying this isn't a solution, but maybe you just want to print some feedback without creating an error condition.
I think you can achieve the result you are looking for by changing
[PRINT 'Hello World'] to [SELECT 'Hello World']
I think this will create a single row of data in a result set with the text you wanted in it, that should show up in fetchall, and see if you get the results you are expecting.
Hope that helps provide an alternative you can try!
Use RAISERROR over PRINT. Use it with NOWAIT to get output immediately. I don't know how to handle this in python, but in ADO.NET you can use the InfoMessage event on SqlConnection. Maybe there is something similar in Python.
Related
I'm using TOAD for Oracle. I'm trying to execute a stored procedure with two parameters - one IN and one OUT. It looks like this:
PROCEDURE get_stuff (
parm_1 IN VARCHAR2,
parm_2 OUT currefcursor)
In the SQL Editor window in TOAD, I've tried various things to no avail. I'm sure this is something simple that I'm missing, 'cause I've tried all sorts of things I've seen in other solutions here at Experts Exchange, but can't get past various errors. Here's what I think should work from what I've seen here:
var p1 VARCHAR2 := 'some text';
var p2 currefcursor;
EXEC get_stuff( :p1, :p2 );
When I run this, though, the SQL Editor pops up a window titled 'Variables' that appears to be looking for a value. No matter whether I put something in the 'Value' textbox or not, when I click OK, it says:
ORA-00900: invalid SQL statement
and highlights the 'var' in front of p1.
Please tell me what I'm missing!
Status Solved Priority Medium Security Public Views 21999
As the second parameter is OUT, you have to declare the variable which will accept that value. Here's how; I don't know what currefcursor type is - I guess you do.
declare
l_out currefcursor;
begin
get_stuff(:p1, l_out);
end;
/
A simple option to view the result would be this: put this code into the editor and run it as a script; the result will be displayed in the Script Output tab.
variable l_out currefcursor
exec get_stuff(:p1, :l_out);
print l_out
Or, you could even create a wrapper function which returns cursor, and then select from it:
create or replace function f_get_stuff(p1 in number)
return currefcursor
is
l_out currefcursor;
begin
get_stuff(p1, l_out);
return l_out;
end;
/
select f_get_stuff(:p1) from dual;
You can use Toad to execute without writing the execution harness yourself as well. Here is one method using the Schema Browser. Select your object and right-click > Execute.
You are presented with a dialog asking for your input parameters. Set your inputs and you can see the generated execution harness below. You can also use this generated code as an educational guide to see one method of writing the code yourself.
Click OK and your function/procedure is executed and results are shown.
I use CakePhp for a little application. In this application I store some store procedures (I use mssql). Now I want to execute theses store procedures and want to use the result set.
If I call a store procedure without any parameters i get want I want without any problems. But when i call another store procedure with parameters i get the error "Invalid cursor state"). I did some research and i understood that there it seemed to be that i execute multiple select because of the result-state.
In CakePhp i call:
This is running without any problems
$res = $db->query("Exec storeProcedureWithoutParams");
Here I get the error with the cursor
$res = $db->query("Exec storeProcedureWithParams 'param1'");
The store procedures are very simple:
CREATE PROCEDURE [dbo].[storeProcedureWithoutParams]
AS
SELECT [u1]
,[u2]
,[u3]
,[u4]
,[u5]
,[u6]
FROM [testdb].[dbo].[test]
CREATE PROCEDURE [dbo].[storeProcedureWithParams]
#test nvarchar(50)
AS
SELECT [u1]
,[u2]
,[u3]
,[u4]
,[u5]
,[u6]
FROM [testdb].[dbo].[test]
where [u6] <> #test
If I execute the both queries directly at the database I get two return. The first one is the result of the select-statement and the second one is the result-set. If I understood it right, is this the problem because i get two results (thats why the cursor-error). BUT I don't know how to solve it and I don't know how to get only the result of the select-statement without the return-state?
Can anybody help me?
Thank you very much!
Greetz
V
Sorry for the late answer, but I'll add it here for testing purposes, as there aren't any full answers for this question.
Not sure 100%, but seems that when there is some kind of message output along the query results, it gives the "invalid cursor state". Adding SET NOCOUNT ON it solved to me.
My co-worker is being unsafe with his code and is allowing a user to upload an SQL file to be run on the server.
He strips out any key words in the file such as "EXEC", "DROP", "UPDATE", "INSERT", "TRUNC"
I want to show him the error of his ways by exploiting his EXEC ( #sql )
My first attempt will be with 'EXEXECEC (N''SELECT ''You DRDROPOPped the ball Bob!'')'
But he might filter that all out in a loop.
Is there a way I can exploit my co-worker's code? Or is filtering out the key words enough?
Edit: I got him to check in his code. If the code contains a keyword he does not execute it. I'm still trying to figure out how to exploit this using the binary conversion.
Tell your co-worker he's a moron.
Do an obfuscated SQL query, something like:
select #sql = 0x44524f5020426f627350616e7473
This will need some tweaking depending on what the rest of the code looks like, but the idea is to encode your code in hex and execute it (or rather, let it be executed). There are other ways to obfuscate code to be injected.
You've got a huge security hole there. And the funny part is, this is not even something that needs to be reinvented. The proper way to stop such things from happening is to create and use an account with the correct permissions (eg: can only perform select queries on tables x, y and z).
Have a look at ASCII Encoded/Binary attacks ...
should convince your friend he is doomed.. ;)
And here some help on how to encode the strings ..
Converting a String to HEX in SQL
Is there a way to write a message to the console? I'd like to write some debug data if it's possible.
The PRINT command emits a message that may be shown in a console depending on what tool you're using:
PRINT 'Hello, world!'
Not all clients necessarily show these messages though.
You mean PRINT?
For example:
PRINT 'hello world'
For long-running operations, instead of PRINT, you might need to use the RAISERROR with NOWAIT option workaround, since the messages display is cached.
Higher overhead but you can log to the event logging system with xp_logevent.
Why does the PRINT statement in T-SQL seem to only sometimes work? What are the constraints on using it? It seems sometimes if a result set is generated, it becomes a null function, I assumed to prevent corrupting the resultset, but could it's output not go out in another result set, such as the row count?
So, if you have a statement something like the following, you're saying that you get no 'print' result?
select * from sysobjects
PRINT 'Just selected * from sysobjects'
If you're using SQL Query Analyzer, you'll see that there are two tabs down at the bottom, one of which is "Messages" and that's where the 'print' statements will show up.
If you're concerned about the timing of seeing the print statements, you may want to try using something like
raiserror ('My Print Statement', 10,1) with nowait
This will give you the message immediately as the statement is reached, rather than buffering the output, as the Query Analyzer will do under most conditions.
The Print statement in TSQL is a misunderstood creature, probably because of its name. It actually sends a message to the error/message-handling mechanism that then transfers it to the calling application. PRINT is pretty dumb. You can only send 8000 characters (4000 unicode chars). You can send a literal string, a string variable (varchar or char) or a string expression. If you use RAISERROR, then you are limited to a string of just 2,044 characters. However, it is much easier to use it to send information to the calling application since it calls a formatting function similar to the old printf in the standard C library. RAISERROR can also specify an error number, a severity, and a state code in addition to the text message, and it can also be used to return user-defined messages created using the sp_addmessage system stored procedure. You can also force the messages to be logged.
Your error-handling routines won’t be any good for receiving messages, despite messages and errors being so similar. The technique varies, of course, according to the actual way you connect to the database (OLBC, OLEDB etc). In order to receive and deal with messages from the SQL Server Database Engine, when you’re using System.Data.SQLClient, you’ll need to create a SqlInfoMessageEventHandler delegate, identifying the method that handles the event, to listen for the InfoMessage event on the SqlConnection class. You’ll find that message-context information such as severity and state are passed as arguments to the callback, because from the system perspective, these messages are just like errors.
It is always a good idea to have a way of getting these messages in your application, even if you are just spooling to a file, because there is always going to be a use for them when you are trying to chase a really obscure problem. However, I can’t think I’d want the end users to ever see them unless you can reserve an informational level that displays stuff in the application.
Query Analyzer buffers messages. The PRINT and RAISERROR statements both use this buffer, but the RAISERROR statement has a WITH NOWAIT option. To print a message immediately use the following:
RAISERROR ('Your message', 0, 1) WITH NOWAIT
RAISERROR will only display 400 characters of your message and uses a syntax similar to the C printf function for formatting text.
Please note that the use of RAISERROR with the WITH NOWAIT option will flush the message buffer, so all previously buffered information will be output also.
I recently ran into this, and it ended up being because I had a convert statement on a null variable. Since that was causing errors, the entire print statement was rendering as null, and not printing at all.
Example - This will fail:
declare #myID int=null
print 'First Statement: ' + convert(varchar(4), #myID)
Example - This will print:
declare #myID int=null
print 'Second Statement: ' + coalesce(Convert(varchar(4), #myID),'#myID is null')
For the benefit of anyone else reading this question that really is missing print statements from their output, there actually are cases where the print executes but is not returned to the client. I can't tell you specifically what they are. I can tell you that if you put a go statement immediately before and after any print statement, you will see if it is executed.
Do you have variables that are associated with these print statements been output? if so, I have found that if the variable has no value then the print statement will not be ouput.