我有一个用C#编写的应用程序,它连接到数据库并分析其数据,数据库存储有关自动化测试执行的信息,我想做的是检索那些满足上述条件的测试。但是我们有不同的项目,并且将支持越来越多,所以我不想为每个项目构建不同的过程,但是传递名称 - 第二个参数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
感谢您的任何建议!
答案 0 :(得分:1)
在你的字符串中你有@build
- 这被解释为一个字符串。在您执行@SQL
时,它不包含这样的变量,因此您将失败。
您需要直接连接值:
SET @SQL = 'insert '+@result+'select testcase_id, fail_percentage FROM [BuildTestResults].[dbo].['+@deployname+'TestCaseExecution]
where build_id = '+@build+' and fail_percentage >= 70'
您也需要在执行之间执行此操作。
答案 1 :(得分:0)
您的示例存在一些问题。然而,这是一个总体考虑因素。
变量(表和/或标量)仅在定义它们的StoredProcedure中可见。并且调用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_EXECUTESQL
内看到行正在处理。在这种情况下,您可能需要重新安排一些事情(使用输出参数,或在@SQL中嵌入循环等)。
任何可以执行此SP和/或控制@deploy参数中的值的人都可能在您的数据库中造成严重破坏。
例如......你能将所有TestCaseExecutions存储在同一个表中吗?但是有一个额外的字段:TestCaseID
*(甚至是TestCaseName
)?
然后,您不需要构建动态SQL来控制您正在处理的数据集。相反,您只需在查询中添加WHERE TestCaseID = @TestCaseID
...