【发布时间】:2018-03-14 22:22:14
【问题描述】:
我正在尝试从 Python3 执行 .sql 文件。 下面是我正在尝试的python代码
import time
userdate=time.strftime("%m_%d_%H_%M%S")
import pypyodbc as pyodbc
db_host='hostname\DBTEST'
db_name='dbname'
conn='Driver={SQL Server};Server=' + db_host + ';Database=' +db_name +
';Trusted_Connection=yes;'
db=pyodbc.connect(conn)
cursor=db.cursor()
file=open('C:\\abc\\xyz.sql','r')
line=file.read()
sql_cmd=line.split('\n')
for x in sql_cmd:
cursor.execute(x)
下面是 xyz.sql 脚本
DECLARE @XML XML;
DECLARE @FileName VARCHAR(1000);
DECLARE @Id UNIQUEIDENTIFIER
SELECT @Id = NEWID()
SELECT @FileName = 'ggg.xml'
SELECT @XML = '<Model>
....xml tags here...
....
</Model>'
IF EXISTS (SELECT * FROM tablename CM WHERE CM.columnname = 'test') BEGIN
UPDATE CM
SET CM.pn = '01-00001',
CM.rev= '06',
CM.Model = @XML,
CM.ModifiedOn = GETUTCDATE()
FROM cm.tablename CM
WHERE CM.columnname= 'test'
PRINT 'Updated ' + @FileName
END ELSE BEGIN
INSERT INTO cm.tablename(cmID, MN, CMType, Description, PN, Rev, CM,
RowStatus, ModifiedBy, ModifiedOn)
SELECT @Id, 'test123', 'abc.1', '', '01-00011', '01', @XML, 'A',
'74E8A3E0-E5CA-4563-BD49-12DFD210ED92', GETUTCDATE()
PRINT 'Inserted ' + @FileName
END
运行 python 代码时出现以下错误。
pypyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC SQL
Server Driver][SQL Server]Must declare the scalar variable "@Id".')
DECLARE @XML XML;
DECLARE @FileName VARCHAR(1000);
DECLARE @Id UNIQUEIDENTIFIER
SELECT @Id = NEWID()
进程以退出代码 1 结束
注意:如果我从 M/S SQL Management studio (sql server 2016) 运行 sql 查询,它运行成功。 对此的任何帮助将不胜感激。
【问题讨论】:
-
您的某些
DECLARE和SEELCT行以分号结尾,而其他行则没有。尝试更一致地使用分号,看看会发生什么。 -
感谢您的意见。 lines1=line1.replace('\n', ' ') 似乎可以解决问题。我也去掉了分号,因为不需要它们。 file = open('C:\\abc\\xyz.sql', 'r') line = file.read() lines = line.replace('\n', ' ') cursor.execute(lines)跨度>
-
让上述“替换”kludge 工作相当幸运,请参阅我的答案以获得更简单和更安全的方法。 “替换” 杂乱无章是不安全的,因为它可以让您在以后遇到意外(想象一下,如果您不小心使用空字符串替换行终止符会发生什么 - 一个难以发现的错误)。另外,请注意,SQL 不是一次执行一行(无论如何都不会工作,请参阅我的答案)。相反, cursor.execute 只被调用一次,并被传递整个(修改后的)查询。顺便说一句,分号作为问题的原因几乎可以肯定是一个红鲱鱼。
-
从我的评论中罢工“无论如何都行不通”。我担心的是超出范围的错误;从那以后,我发现(SQL)范围界定是基于连接完成的,而不是基于“cursor.execute”,这意味着逐行使用 cursor.excute 不会导致范围界定问题。
标签: python sql selenium sql-server-2016