SQL python 脚本中的 SQL 参数 SQL proc

SQL param in python script in SQL proc

我正在尝试使用传递给 Python 的动态 SQL 来执行,但无法获得适用于 @key 的正确引号组合。这是过程:

    create procedure [dbo].[pr_select_to_html_table]
    (
        @key        varchar(100),
        @sql_query  nvarchar(max) = null
    )
    AS

    DECLARE @NewScript NVARCHAR(MAX) 
    SET @NewScript  = N'
    import pandas as pd
    import pyodbc

    def exec_sql (query) :
        # execute sql query with no return
        cnxn_p = pyodbc.connect("driver={odbc driver 17 for sql server};server=localhost;DATABASE=trader;trusted_connection=yes;")
        cursor_p = cnxn_p.cursor()
        try:
            cursor_p.execute(query)
        except pyodbc.Error as err:
                print(err)
        cnxn_p.commit()

    #Read Data From Input @input_data_1 
    df = my_input_data
    df.index = df.index+1

    result = df.to_html()
    sql = "insert into wrk.html_table (key,html_result) values (''' + @key + ''' ,''" + result + "'')"
    exec_sql(sql)
        '

        EXEC sp_execute_external_script
          @language = N'Python'
        , @Script = @NewScript
        , @input_data_1 = @sql_query
        , @input_data_1_name = N'my_input_data'

Python 提供了两个错误,第一个我认为可能不适用的是:UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access setattr(结果,“var_info”,var_info)

第二个 Python 错误是:('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near关键字 'key'. (156) (SQLExecDirectW)")

三重单引号不起作用,单双单也不行。

(是的,我将 SQL 从 SQL 服务器传递到 Python,然后连接到 SQL 服务器并执行 SQL。to_html() 方法是值得努力的)。

如果您尝试现在正在做的事情,您将遇到严重的 SQL 注入问题。

此处最好的解决方案是将 HTML 作为 OUTPUT 参数传回:

create procedure [dbo].[pr_select_to_html_table]
(
    @key        varchar(100),
    @sql_query  nvarchar(max) = null
)
AS

DECLARE @NewScript NVARCHAR(MAX) 
SET @NewScript  = N'
import pandas as pd

#Read Data From Input @input_data_1 
df = my_input_data
df.index = df.index+1

html = df.to_html()
     '

DECLARE @html nvarchar(max);

EXEC sp_execute_external_script
       @language = N'Python'
     , @Script = @NewScript
     , @input_data_1 = @sql_query
     , @input_data_1_name = N'my_input_data'
     , @params = N'@html nvarchar(max) OUTPUT'
     , @html = @html OUTPUT;

insert into wrk.html_table (key, html_result)
values (@key, @html);

您的另一个选择是使用参数从 Python 端进行插入。我觉得这不太干净,因为可以通过上面的参数返回标量值,并且可以通过 @output_data_1_name

返回数据帧
create procedure [dbo].[pr_select_to_html_table]
(
    @key        varchar(100),
    @sql_query  nvarchar(max) = null
)
AS

DECLARE @NewScript NVARCHAR(MAX) 
SET @NewScript  = N'
import pandas as pd
import pyodbc

#Read Data From Input @input_data_1 
df = my_input_data
df.index = df.index+1

result = df.to_html()
sql = """
insert into wrk.html_table (key, html_result)
values (?, ?)"""

# execute sql query with no return
cnxn_p = pyodbc.connect("driver={odbc driver 17 for sql server};server=localhost;DATABASE=trader;trusted_connection=yes;")
cursor_p = cnxn_p.cursor()
try:
    cursor_p.execute(query, key, result)
except pyodbc.Error as err:
        print(err)
cnxn_p.commit()

exec_sql(sql)
     '

EXEC sp_execute_external_script
       @language = N'Python'
     , @Script = @NewScript
     , @input_data_1 = @sql_query
     , @input_data_1_name = N'my_input_data'
     , @params = N'@key varchar(100)'
     , @key = @key;