pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server 驱动程序][SQL Server]附近语法不正确

Ng *_* Hà 8 python sql-server beautifulsoup pyodbc

我正在使用 python 3.9 使用 pyobc 将多个新闻列表从 google rss news 插入到带有参数的 SQL 表中,但总是出现以下编程错误:

\n
\n

Cursor.execute(query) pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server 驱动程序][SQL Server]'c\xc3\xb2'\n 附近的语法不正确。(102) (SQLExecDirectW )”)

\n
\n

我检查了sql表,发现实际上有一些记录已成功导入到SQL(15条记录),但不是全部(30条记录)

\n

下面是我的所有代码,请帮忙!

\n
import bs4\nfrom bs4 import BeautifulSoup as soup\nfrom urllib.request import urlopen\nimport pyodbc\n\nnews_url="https://news.google.com/rss?hl=vi&gl=VN&ceid=VN:vi"\nClient=urlopen(news_url)\nxml_page=Client.read()\nClient.close()\nsoup_page=soup(xml_page,"xml")\nnews_list=soup_page.findAll("item")\n\ncnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ADMIN;DATABASE=NewsCollect2')\ncursor = cnxn.cursor()\n\nfor news in news_list:\n    query = f"insert into news2(Title,Source1,Time1) values (N'"+news.title.text+"',N'"+news.source.text+"',N'"+news.pubDate.text+"')"\n    cursor.execute(query)\n    cursor.commit()\ncursor.close()\ncnxn.close()\n
Run Code Online (Sandbox Code Playgroud)\n

p/s 我尝试提取到 txt 文件,它工作得很好

\n

Par*_*ait 6

正如 @PanagiotisKanavos 所评论的,使用行业推荐的 SQL 参数化最佳实践,它超越了 Python 和 SQL Server,而是任何应用程序层代码和任何SQL 兼容的数据库。

此方法不仅可以安全地转义用户提交的值,还可以避免特殊字符的破坏,例如根据您的情况的重音符号,甚至字符串中的引号。此外,您还可以增强代码的可读性、可维护性和效率。甚至考虑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()
Run Code Online (Sandbox Code Playgroud)


小智 6

在python3中,您需要在 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')
Run Code Online (Sandbox Code Playgroud)