使用参数化查询在远程服务器上执行EXEC

时间:2017-04-18 12:33:10

标签: sql-server ruby jdbc jruby

我正在尝试在链接服务器上运行以下SQL;

INSERT INTO dbo.test (FirstName, LastName)Values(?,?)
带有来自(dbo.test)的本地SQL服务器的别名的链接服务器上存在

DATALOADER01

因此,我想要执行的查询是;

EXEC('INSERT INTO dbo.test (FirstName, LastName)Values(?,?)') AT [DATALOADER01]

执行SQL的Ruby代码;

def connect(server, database)
    url = "jdbc:sqlserver://%s;databaseName=%s;integratedSecurity=true" % [server, database]
    return java.sql.DriverManager.get_connection(url)
end

    def execute_q(statement, options = [])
        @conn = connect('sql','master')
        ps = @conn.prepareStatement(statement)
        options.each_with_index do |opt, index|
            set_param(ps, index.to_i + 1, opt)  
        end
        ps.execute()
    end

我得到的错误是'索引1超出范围'

当我将非参数化查询传递给execute_q时,代码可以正常工作。例如;

EXEC('CREATE TABLE dbo.test2 (Test nvarchar(max))') AT [DATALOADER01]

没有权限问题,链接设置正确,所以我不担心那里有问题。

我感谢我可以在不使用EXEC的情况下插入链接服务器,但是MERGE语句不起作用,除非这样做。

1 个答案:

答案 0 :(得分:2)

如果您使用

EXEC('INSERT INTO dbo.test (FirstName, LastName)Values(?,?)') AT [DATALOADER01]

您只是要求SQL Server将字符串'INSERT INTO dbo.test (FirstName, LastName)Values(?,?)'转发到链接服务器。它不知道参数。为了能够提供参数,您需要将它们显式发送为您正在执行的exec语句的一部分。所以你需要使用:

EXEC('INSERT INTO dbo.test (FirstName, LastName)Values(?,?)', ?, ?) AT [DATALOADER01]

在此处向exec命令添加两个参数,然后允许SQL Server识别您要传递参数。