【问题标题】:Send a SQL-statement as a parameter to a stored procedure将 SQL 语句作为参数发送到存储过程
【发布时间】:2019-07-23 06:01:19
【问题描述】:

我想知道是否有任何聪明的解决方案可以将整个 SQL 语句作为参数发送到已经保存日期参数的存储过程。

见下文。

CREATE procedure sp_GetDataByDate
 @startdate datetime,
 @enddate datetime,
 @sqlStatement varchar(max)
as  
begin
   -- Here I want my SELECT-anything-somehow-statement
   @sqlStatement
   WHERE dbo.DummyDataTable.CreatedDT BETWEEN @startdate AND @enddate
end

一种解决方案,您首先使用 SQL 语句并使用该数据创建一个临时表,以便稍后使用日期参数过滤出您想要的内容,但它可能会很重,因为该数据库中有很多数据.

谢谢

【问题讨论】:

  • 你最好不要这样做。这将为您的安全性带来一个巨大的漏洞,并为 SQL 注入敞开大门。
  • 是的。我愿意接受其他解决方案来解决这个问题。
  • 你想达到什么目标?是从不同的表中选择还是从不同的表中选择不同的列?听起来像是XY-problem
  • 阅读一下@Denis 所说的内容:安全风险。 red-gate.com/hub/product-learning/sql-prompt/…
  • 绝对是 XY 问题。你在这里尝试解决的“真正的”问题是什么?

标签: sql-server tsql stored-procedures dynamic-sql


【解决方案1】:

您可以在 sql server 中使用 DQE(动态查询执行),您可以使用此功能创建具有字符串功能的 TSQL 并执行它。

但是这个解决方案存在一些安全和性能问题。

在这种情况下,黑客可以通过 SQL 注入攻击来攻击您的站点,并且可能会出现一些性能问题,例如 sql server 上的计划捕获和参数嗅探。

最好的解决方案是创建不同的 SP 来加载信息。

 CREATE PROCEDURE sp_GetDataByDate
     @startdate datetime,
     @enddate datetime,
     @sqlStatement varchar(max)
    AS  
    BEGIN
       -- Here I want my SELECT-anything-somehow-statement
     SET @sqlStatement +=' WHERE dbo.DummyDataTable.CreatedDT BETWEEN '+CHAR(39)+ CONVERT(NVARCHAR , @startdate , 120 )+CHAR(39)+  ' AND ' +CHAR(39)+ CONVERT(NVARCHAR , @enddate , 120 )+CHAR(39)

     PRINT @sqlStatement 

     EXEC(@sqlStatement )
    END

DQE Microsoft Doc

【讨论】:

  • 想想当你从你的前端sqlStatement = 'DROP TABLE dbo.DummyDataTable; --'得到什么时候会发生什么
  • 就像我在另一个(现已删除)答案中所说的那样,这是一个巨大的安全问题,应该使用。
  • @nipple1450 - Denis Rubashkin 是绝对正确的 - 即使是参数也无法让您免于编写 SQL 脚本的这种糟糕方式。您还需要编译传递代码的开销(取决于注入 SQL 的复杂性)。
  • @Paul 是的,我同意你的观点,但我只是回答他的问题,我会改变我的答案并告诉他替代方式。谢谢
  • @nipple1450 只是因为还没有人直截了当地说 - 用户可以很容易地更改前端的值,甚至完全绕过您的前端并将他们想要的任何内容发送到后端。你不能相信来自前端的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多