Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将字符串变量传递到过程中,并将其添加到查询中_Sql_Sql Server 2008_Stored Procedures_Concatenation - Fatal编程技术网

Sql 将字符串变量传递到过程中,并将其添加到查询中

Sql 将字符串变量传递到过程中,并将其添加到查询中,sql,sql-server-2008,stored-procedures,concatenation,Sql,Sql Server 2008,Stored Procedures,Concatenation,我有一个用C#编写的应用程序,它连接到数据库并分析其数据,数据库存储有关自动测试执行的信息,我想做的是检索满足上述给定条件的测试。但是我们有不同的项目,并且将支持越来越多的项目,所以我不想为每个项目构造不同的过程,而是将name-2nd参数deploy作为参数传递,这样查询将依赖于项目并将数据返回到应用程序,然后我将在报告中发送它 目前看来是这样的: CREATE PROCEDURE [dbo].[SuspectsForFalsePositive](@build_id INT, @deploy

我有一个用C#编写的应用程序,它连接到数据库并分析其数据,数据库存储有关自动测试执行的信息,我想做的是检索满足上述给定条件的测试。但是我们有不同的项目,并且将支持越来越多的项目,所以我不想为每个项目构造不同的过程,而是将name-2nd参数deploy作为参数传递,这样查询将依赖于项目并将数据返回到应用程序,然后我将在报告中发送它

目前看来是这样的:

CREATE PROCEDURE [dbo].[SuspectsForFalsePositive](@build_id INT, @deploy VARCHAR(25)) 
AS
BEGIN

    SET NOCOUNT ON;

    DECLARE @i int, @build int, @deployname varchar(25), @SQL varchar(max)
    DECLARE @result table (tc int, fp float)
    SET @i = 0
    SET @build = @build_id
    SET @deployname = @deploy

    SET @SQL = 'insert '+@result+'select testcase_id, fail_percentage FROM [BuildTestResults].[dbo].['+@deployname+'TestCaseExecution]
                   where build_id = @build and fail_percentage >= 70'

--INSERT @result select testcase_id, fail_percentage FROM [BuildTestResults]
--.[dbo].[ABCTestCaseExecution]
--where build_id = @build and fail_percentage >= 70
--commented works
    EXEC(@SQL)
    WHILE (@@rowcount = 0)
    BEGIN
    SET @build = @build - 1
    EXEC(@SQL)
--INSERT @result select testcase_id, fail_percentage FROM [BuildTestResults].[dbo]. --[ABCTestCaseExecution]
--where build_id = @build and fail_percentage >= 70
--commented works
    END
    select * from @result order by fp DESC
END
GO

谢谢你的建议

在字符串中有
@build
-这被解释为字符串。当您执行
@SQL
时,它不包含这样的变量,因此您会得到一个失败

您需要直接连接该值:

SET @SQL = 'insert '+@result+'select testcase_id, fail_percentage FROM [BuildTestResults].[dbo].['+@deployname+'TestCaseExecution]
                   where build_id = '+@build+' and fail_percentage >= 70'

您还需要在执行之间执行此操作。

您的示例存在一些问题。然而,这是一个非常重要的考虑因素

变量(表和/或标量)仅在定义它们的StoredProcess中可见。调用
EXEC(@SQL)
就是调用一个存储的。这意味着@result表和其他参数对正在执行的动态SQL都不可见

在表方面,您可以通过创建临时表来解决这个问题。对于标量变量,可以在使用
SP_EXECUTESQL
而不是
EXEC
时传递它们

我目前没有访问sql server的权限,但也许像这样的东西可以让你开始你的旅程

CREATE PROCEDURE [dbo].[SuspectsForFalsePositive](@build_id INT, @deploy VARCHAR(25)) 
AS
BEGIN

  SET NOCOUNT ON;

  DECLARE
    @i          int,
    @build      int,
    @deployname varchar(25),
    @SQL        varchar(max)

  CREATE TABLE #result (
    tc int,
    fp float
  )

  SELECT
    @i          = 0,
    @build      = @build_id,
    @deployname = @deploy

  SET @sql = ''
  SET @sql = @sql + ' INSERT INTO #result'
  SET @sql = @sql + ' SELECT testcase_id, fail_percentage'
  SET @sql = @sql + '   FROM [BuildTestResults].[dbo].['+@deployname+'TestCaseExecution]'
  SET @sql = @sql + '  WHERE build_id = @build and fail_percentage >= 70'

  SP_EXECUTESQL
     @SQL,
     '@build INT',
     @build

  WHILE (@@rowcount = 0)
  BEGIN
    SET @build = @build - 1
     SP_EXECUTESQL
       @SQL,
       '@build INT',
       @build
  END

  SELECT * FROM #result ORDER BY fp DESC

END
GO

我还想到@rowcount现在可能会在
SP\u EXECUTESQL
中看到正在处理的行。在这种情况下,您可能需要重新安排一些事情(使用输出参数,或者将循环嵌入@SQL中,等等)


总的来说,感觉有点笨重。有了关于模式等的更多信息,就有可能避免使用动态SQL。这将有几个好处,但有一个特别的好处:
-现在,您对@deploy参数的SQL注入攻击是开放的

任何能够执行此SP和/或控制@deploy参数中的值的人都可能在数据库中造成破坏


例如。。。您能将所有TestCaseExecutions存储在同一个表中吗?但是有一个额外的字段:
TestCaseID
*(甚至
TestCaseName


这样,就不需要构建动态SQL来控制正在处理的数据集。相反,您只需将TestCaseID=@TestCaseID添加到您的查询中…

您好,我忘记了这一点,但是result和deployname仍然存在问题。@Artur-它们将是类似的问题。你能解释一下(在你的问题中)你到底想达到什么目的吗?与其给我们你的解决方案(这可能不合适),不如解释一下你正在遇到的问题以及应该解决的问题-我们可以建议一种不同的、更好的方法。是的,当然,问题如下-我有一个用C#编写的应用程序,它连接到数据库并分析其数据,数据库存储有关自动测试执行的信息,我想做的是检索满足上述给定条件的测试。但是我们有不同的项目,并且将支持越来越多的项目,因此我不想为每个项目构造不同的过程,而是将name-2nd参数deploy作为参数传递,以便查询将取决于项目并将数据返回到应用程序,然后我会将其发送到报告中。@Artur-请编辑您的问题并在那里添加详细信息。注释不是存放这些信息的好地方。如何将“项目”存储在数据库中?不同的表格?我建议你读Erland Sommarskog的。