使用Pypyodbc插入带单引号的格式化字符串

时间:2016-09-06 13:54:49

标签: python sql-server pypyodbc

我正在尝试使用Pypyodbc插入网络路径作为字符串值:

    def insert_new_result(self, low, medium, high, reportpath):
    reportpath = "'" + reportpath + "'"
    self.insertsql = (
        """INSERT INTO [dbo].[Results] ([low],[medium], [high], [date]) VALUES
        ({low},{medium},{high}, GETDATE(),{reportpath})"""
        .format(low=low, medium=medium, high=high, reportpath=reportpath))
    self.conection.cursor().execute(self.insertsql).commit()

这是评估

'INSERT INTO [dbo].[Results] ([low],[medium], [high], [date]) VALUES
            (0,2,2, GETDATE(),\\'\\\\share\\dev-temp\\report_10b29ef6-7436-11e6-ab96-534e57000000.html\\')'

注意共享路径开头的额外单引号,导致无效的sql错误。我尝试了一些像.format()这样的东西,构建字符串并转义但是它在第一个\后继续包含单引号

如何让self.insertsql评估为

'INSERT INTO [dbo].[Results] 
     ([low],[medium], [high], [date]) 
 VALUES 
     (0,2,2, GETDATE(),'\\\\share\dev-temp\report_10b29ef6-7436-11e6-ab96-534e57000000.html\')'

1 个答案:

答案 0 :(得分:0)

如果您正在使用string.format(),那么您正在创建动态SQL ,这会让您对 SQL注入的所有侮辱感敞开,就像弄乱字符串分隔符和逃跑。您应该只使用参数化查询,如下所示:

self.insertsql = """\
INSERT INTO [dbo].[Results] ([low],[medium], [high], [date], [reportpath]) 
    VALUES (?, ?, ?, GETDATE(), ?)
"""
self.params = (low, medium, high, reportpath, )
self.conection.cursor().execute(self.insertsql, self.params).commit()

编辑重新评论

作为简化的自包含测试,代码

conn = pypyodbc.connect(conn_str, autocommit=True)
crsr = conn.cursor()

sql = """\    
CREATE TABLE #Results 
    (
        id INT IDENTITY PRIMARY KEY, 
        reportpath NVARCHAR(255)
    )
"""
crsr.execute(sql)

# test data
reportpath = r"\\share\dev-temp\report_10b29ef6-7436-11e6-ab96-534e57000000.html"

sql = "INSERT INTO #Results (reportpath) VALUES (?)"
params = (reportpath, )
crsr.execute(sql, params)

crsr.execute("SELECT * FROM #Results")
row = crsr.fetchone()
print(row)

显示此

(1, u'\\\\share\\dev-temp\\report_10b29ef6-7436-11e6-ab96-534e57000000.html')