从 R/DBI/ODBC 调用 SQL 服务器上的存储过程时避免动态生成 SQL
Avoid dynamic SQL generation when calling stored procedure on SQL server from R/DBI/ODBC
使用 SQL Server
上的探查器通过 DBI
/odbc
监视 stored procedure
调用,表明生成了动态 SQL / 准备好的语句:
con <- DBI::dbConnect(odbc::odbc(),...)
dbGetQuery(con, "EXEC sp_helptext 'sys.sp_addlogin';")
SQL Server
的结果:
declare @p1 int
set @p1=2
exec sp_prepexec @p1 output,NULL,N'EXEC sp_helptext ''sys.sp_addlogin'';'
select @p1
为了数据库安全和性能,我们禁用了动态 SQL 调用,所以我想直接调用:
EXEC sp_helptext 'sys.sp_addlogin';
不确定动态 SQL 覆盖是由 DBI
还是 odbc
驱动程序生成的。
有办法避免吗?
我在 odbc
包文档中找到了我要找的东西:direct execution。
The odbc package uses Prepared Statements to compile the query once and reuse it, allowing large or repeated queries to be more efficient. However, prepared statements can actually perform worse in some cases, such as many different small queries that are all only executed once.
Because of this the odbc package now also supports direct queries by specifying immediate = TRUE
.
这将使用准备好的语句:
dbGetQuery(con, "EXEC sp_helptext 'sys.sp_addlogin';")
declare @p1 int
set @p1=2
exec sp_prepexec @p1 output,NULL,N'EXEC sp_helptext ''sys.sp_addlogin'';'
select @p1
这将直接执行存储过程:
dbGetQuery(con, "EXEC sp_helptext 'sys.sp_addlogin';",immediate = TRUE)
EXEC sp_helptext 'sys.sp_addlogin';
使用 SQL Server
上的探查器通过 DBI
/odbc
监视 stored procedure
调用,表明生成了动态 SQL / 准备好的语句:
con <- DBI::dbConnect(odbc::odbc(),...)
dbGetQuery(con, "EXEC sp_helptext 'sys.sp_addlogin';")
SQL Server
的结果:
declare @p1 int
set @p1=2
exec sp_prepexec @p1 output,NULL,N'EXEC sp_helptext ''sys.sp_addlogin'';'
select @p1
为了数据库安全和性能,我们禁用了动态 SQL 调用,所以我想直接调用:
EXEC sp_helptext 'sys.sp_addlogin';
不确定动态 SQL 覆盖是由 DBI
还是 odbc
驱动程序生成的。
有办法避免吗?
我在 odbc
包文档中找到了我要找的东西:direct execution。
The odbc package uses Prepared Statements to compile the query once and reuse it, allowing large or repeated queries to be more efficient. However, prepared statements can actually perform worse in some cases, such as many different small queries that are all only executed once. Because of this the odbc package now also supports direct queries by specifying
immediate = TRUE
.
这将使用准备好的语句:
dbGetQuery(con, "EXEC sp_helptext 'sys.sp_addlogin';")
declare @p1 int
set @p1=2
exec sp_prepexec @p1 output,NULL,N'EXEC sp_helptext ''sys.sp_addlogin'';'
select @p1
这将直接执行存储过程:
dbGetQuery(con, "EXEC sp_helptext 'sys.sp_addlogin';",immediate = TRUE)
EXEC sp_helptext 'sys.sp_addlogin';