Function sequence error in PYODBC - python

I am using pyodbc to connect to a database and extract certain data from it.
Here is my code:
con = pyodbc.connect("driver={SQL Server};server= MyServer;database= MyDatabase;trusted_connection=true")
cursor = con.cursor()
SQL_command = """
SELECT RowID = ISNULL
(
(
SELECT TOP 1 RowID
FROM [MyDatabase].[admin].[MyTable]
WHERE [queue] = ? and processed IS NULL
)
,-1
)
"""
cursor.execute(SQL_command, queueNumber)
cursor.commit()
con.commit()
result_set = cursor.fetchall()
And I got following error after I run above code:
pyodbc.Error: ('HY010', '[HY010] [Microsoft][ODBC SQL Server
Driver]Function sequence error (0) (SQLFetch)')
May I know what caused such problem, and how can I fix it?
Thanks.

I believe your problem is the strange commit statements. You only need to commit when inserting or updating records not selecting.
cursor.execute(SQL_command, queueNumber)
result_set = cursor.fetchall()
Also, in the future when using commit, both cursor.commit and con.commit do the same thing, you only need one.
Finally, I'd get used to calling execute with the second arguement as a tuple:
cursor.execute(SQL_command, (queueNumber,))
The way you have it works for pyodbc but is not DB API standard.

I was recieving the two following errors more or less interchangeably:
pyodbc.Error: ('HY010', '[HY010] [Microsoft][ODBC Driver 17 for SQL Server]Function sequence error (0) (SQLGetData)')
pyodbc.Error: ('HY007', '[HY007] [Microsoft][ODBC Driver 17 for SQL Server]Associated statement is not prepared (0) (SQLNumResultCols)')
My problem was, that two threads were using the same connection, which led to weird states of the prepared statements. I fixed it by creating a new connection for each thread.

Related

How do I create a copy of a table using PYODBC?

I'm using 32-bit Python along with 32-bit Microsoft Access.
I connect to the database and create a cursor.
conn = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=P:\path\database.accdb;')
c = conn.cursor()
I then read in a table for future use:
c.execute('select * from tbl')
tbl = c.fetchall()
But when I try to make a copy of the table using:
query = 'CREATE TABLE tbl2 LIKE tbl'
c.execute(query)
I get a programming error:
ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error in CREATE TABLE statement. (-3551) (SQLExecDirectW)')
I'm new to PYODBC but this is a pretty basic SQL line. Any tips on what might be wrong?
Due to a lack of documentation, the best way I found to figure this out is to use Microsoft Access to create a template for the query...example below worked.
query = 'SELECT tbl.* INTO tbl2 FROM tbl'
c.execute(query)

pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near

I'm using python 3.9 to insert a list of multiple news from google rss news to SQL table with parameter using pyobc but always getting programming error below:
cursor.execute(query) pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near 'cò'
. (102) (SQLExecDirectW)")
I checked the sql table and found out actually some of records had been imported to SQL successfully (15 records ) but not all of its (30 records)
Below its all of my codes pls help !
import bs4
from bs4 import BeautifulSoup as soup
from urllib.request import urlopen
import pyodbc
news_url="https://news.google.com/rss?hl=vi&gl=VN&ceid=VN:vi"
Client=urlopen(news_url)
xml_page=Client.read()
Client.close()
soup_page=soup(xml_page,"xml")
news_list=soup_page.findAll("item")
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ADMIN;DATABASE=NewsCollect2')
cursor = cnxn.cursor()
for news in news_list:
query = f"insert into news2(Title,Source1,Time1) values (N'"+news.title.text+"',N'"+news.source.text+"',N'"+news.pubDate.text+"')"
cursor.execute(query)
cursor.commit()
cursor.close()
cnxn.close()
p/s I tried to extract to txt file and it worked totally fine
As commented by #PanagiotisKanavos, use the industry recommended best practice of SQL parameterization which goes beyond Python and SQL Server but any application layer code and any SQL-compliant database.
Not only does this method safely escape user-submitted values, you also avoid breakage with special characters such as accent marks per your case and even quotes within the strings. Additionally, you enhance code readability, maintainability, and arguably efficiency. Even consider executemany:
# PREPARED STATEMENT (NO DATA)
query = "insert into news2 (Title, Source1, Time1) values (?, ?, ?)"
# LIST OF TUPLES FOR PARAMS
data = [(news.title.text, news.source.text, news.pubDate.text) for news in newslist]
# EXECUTE STATEMENT AND BIND PARAMS
cursor.executemany(query, data)
cursor.commit()
in python3, you need to add two lines after your conn
import pyodbc as db # forgot the imports
conn = pyodbc.connect(driver=driver, server=serv, database=db,port = prt,
uid=usr, pwd=passwd)
conn.setdecoding(db.SQL_CHAR, encoding='latin1')
conn.setencoding('latin1')

Why I receive error pyodbc.Error: ('HY000', 'The driver did not supply an error!')

I don't understand? Why I receve error: 'HY000', 'The driver did not supply an error!When I insert date time? But when I insert Null all is work. Please help me with it.
My code:
now=now.strftime('%Y-%m-%d %H:%M:%S')
connect = pyodbc.connect("DRIVER={SQL Server};Server=Study;Database=test;Trusted_Connection=yes;", autocommit=False)
cursor=connect.cursor()
cursor.execute("""
use base_for_time insert table_for_time_and_count values (Null,'"""+now+"""',Null,Null,Null)""")
connect.commit()
connect.close()
This might useful.
I think the issue is in your query and in your connection.
update connection:
connect = pyodbc.connect("DRIVER={SQL Server};SERVER=*****;UID=****;PWD=****;TRUSTED_CONNECTION=yes;", autocommit=False)
you're using executing multiple SQL statements in your single execution.
execute your statements one by one or use semicolon(;) instead between two queries.
cursor.execute("use db_name; insert into table_name values (val1,val2,..,valn);")

"Cannot find data type READONLY" error on UPDATE to SQL Server

I've been stuck in this problem for a long time, i hope somebody could enlighten me. I have a sql database i would like to update. Here are some pieces of the code. I extracted data from sql to Python, then apply function hex_to_string & slicing bin and I plan to update the SQL database. I don't have any ID in the database, but I have the DATETIME which differentiates the entry.
query = """ select P from Table """
cnxn = pyodbc.connect(conn_str)
cnxn.add_output_converter(pyodbc.SQL_VARBINARY, hexToString)
cursor: object = cnxn.cursor()
cursor.execute(query)
dtbs= cursor.fetchall()
row_list=[]
ln = len(dtbs)
cursor.execute(query)
for i in range(ln):
row=cursor.fetchval()
result=slicing_bin(row)
result_float = [float("{0:.2f}".format(i)) for i in result]
row_list.append(result_float)
crsr = cnxn.cursor()
crsr.execute(query)
aList = [item[0] for item in crsr.fetchall()]
for aValue in aList:
crsr.execute("""UPDATE Table SET P=? WHERE DATETIME=?""", (row_list, aValue))
crsr.close()
cnxn.commit()
When I run this code, I got an error message,
File
"C:/Users/r/.PyCharmCE2018.3/config/scratches/Finalcombined2.py",
line 64, in
crsr.execute("""UPDATE Access.dbo.M_PWA SET P_PULSES=? WHERE DATETIME=?""", (row_list, aValue)) pyodbc.ProgrammingError: ('42000',
"[42000] [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Column,
parameter, or variable #1: Cannot find data type READONLY. (2715)
(SQLExecDirectW); [42000] [Microsoft][ODBC Driver 11 for SQL
Server][SQL Server]Statement(s) could not be prepared. (8180); [42000]
[Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Parameter or
variable '#P1' has an invalid data type. (2724)")
Please Help, thanks.
Hummm, I would have guessed that Gord was right. That's certainly the first thing I'd look at. Ok, here is a small sample of how I do updates in MS Access, from Python.
#import pypyodbc
import pyodbc
# MS ACCESS DB CONNECTION
pyodbc.lowercase = False
conn = pyodbc.connect(
r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
r"Dbq=C:\\path_here\\Northwind.mdb;")
# OPEN CURSOR AND EXECUTE SQL
cur = conn.cursor()
# Option 1 - no error and no update
cur.execute("UPDATE dbo_test SET Location = 'New York' Where Status = 'Scheduled'");
conn.commit()
cur.close()
conn.close()
Can you adapt this to your specific scenario?

Why is this Python error code: Too Few parameters. Expected1. (-3010) occurring when using pyodbc?

I am writing a python script that executes some SQL code however whenever I call the function containing this SQL it gives me the error:
File "Z:/ ... /Script.py", line 40, in Function
cnxn.execute("""INSERT INTO Table1 VALUES (007, Bond);""")
Error: ('07002', '[07002] [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 1. (-3010) (SQLExecDirectW)')
I have researched this problem and found other posts with the same error but I can't seem to apply the answers given to my code. For example:
facing Too few parameters. Expected 1. (-3010) (SQLExecDirectW)')" error in python program
import pyodbc
conn_str = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=Z:\ ... \DB.accdb;'
)
cnxn = pyodbc.connect(conn_str)
crsr = cnxn.cursor()
cnxn.execute("""INSERT INTO Table1 VALUES (007, Bond);""")
I originally had only single quotes and tried what Navnath said in his answer and use triple quotes but that changed nothing. I believe that my SQL syntax is correct so I don't understand why this approach isn't working and why this error is coming up. Any help would be greatly appreciated!
Your problem seems to be that you're running the .execute() method from the connection rather than from the cursor you have opened. Also, it's always better to be explicit and use bound variables. Try this?
import pyodbc
conn_str = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=Z:\ ... \DB.accdb;'
)
cnxn = pyodbc.connect(conn_str)
crsr = cnxn.cursor()
crsr.execute(
"""
INSERT INTO Table1 (agent_number, agent_last_name) VALUES (?, ?)
""",
('007', 'Bond')
)
Depending on your connection, you may also need to do a .commit() afterwards, since you're inserting, updating, or deleting data. Good luck!

Categories