Reputation: 7408
I have a SQL script like follows:
DECLARE @AGE INT = ?
, @NAME VARCHAR(20) = ?
INSERT INTO [dbo].[new_table] (AGE, NAME)
SELECT @AGE, @NAME
SELECT ID = CAST(SCOPE_IDENTITY() AS INT)
In the table, there is an IDENTITY column ID
which is defined as INT
. Thus the values of the ID
column is increasing as new rows are inserted. And my goal is to take out the
ID that just inserted.
The above code works fine in SQL.
Then I tried to run it in python, using following code:
conn = pyodbc.connect("driver={SQL Server}; server= MyServer; database= MyDatabase"; trusted_connection=true")
cursor = conn .cursor()
SQL_command = """
DECLARE @AGE INT = ?
, @NAME VARCHAR(20) = ?
INSERT INTO [dbo].[new_table] (AGE, NAME)
SELECT @AGE, @NAME
SELECT ID = CAST(SCOPE_IDENTITY() AS INT)
"""
cursor.execute(SQL_command, 23, 'TOM')
result = cursor.fetchall()
However, I've got following error message:
Traceback (most recent call last):
File "C:\Users\wwang\Documents\Aptana Studio 3 Workspace\ComparablesBuilder\test.py", line 119, in
result = cursor.fetchall()
pyodbc.ProgrammingError: No results. Previous SQL was not a query.
So, may I know why the same code cannot work in python? Is my usage of pyodbc is incorrect?
Many thanks.
Upvotes: 1
Views: 2327
Reputation: 107247
It's possible that the multiple statements in your Sql Batch are being interpreted as separate result sets to the Python driver - the first row-count returning statement is the INSERT
statement, which could be the culprit.
Try adding SET NOCOUNT ON;
before your statements, to suppress row counts from non-queries:
SET NOCOUNT ON;
DECLARE @AGE INT = ?
, @NAME VARCHAR(20) = ?
...
SELECT ID = CAST(SCOPE_IDENTITY() AS INT);
Edit
IIRC, some drivers are also dependent on Sql Server's ROW COUNT
to parse result sets correctly. So if the above fails, you might also try:
SET NOCOUNT ON;
DECLARE ...;
INSERT ...;
SET NOCOUNT OFF; -- i.e. Turn back on again so the 1 row count can be returned.
SELECT CAST(SCOPE_IDENTITY() AS INT) AS ID;
Upvotes: 1