2016-06-06 2 views
0

SQL 테이블에서 테스트가 통과하는지 또는 실패 하는지를 문서화하기 위해 일부 SQL 테스트 쿼리를 설정하려고합니다. 이 테스트 쿼리는 여러 개의 별도 데이터베이스에서 실행됩니다.조건부 if/else 문에서 복합 SQL 쿼리 사용

DECLARE @dbname NVARCHAR(200); 
DECLARE @query NVARCHAR(MAX); 

DECLARE db_cursor CURSOR FOR 
SELECT name FROM sys.databases 
WHERE name LIKE '%JMPTIPR%' 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @dbname 

WHILE @@FETCH_STATUS = 0 

BEGIN 

SET @query = CAST(' 
DECLARE @testStatus NVARCHAR(MAX); 
DECLARE @name NVARCHAR(MAX); 
DECLARE @version NCHAR(10); 
DECLARE @testid INT; 
DECLARE @repid INT; 

SELECT @name = Column1 from [' [email protected]+ '].dbo.Table1 
where Column1 = ''File Name'' 
SELECT @version = attributedata from [' [email protected]+ '].dbo.Table1 
where Column1 = ''Version Number'' 
SELECT @testid = COALESCE(MAX(TestNum), 0) FROM [Database1].dbo.Table2; 
SELECT @repid = RepNum FROM [Database1].dbo.Table2 
WHERE Date = (SELECT MAX(Date) FROM [Database1].dbo.Table2) 

IF (
    SELECT COUNT(*) 
    FROM [' [email protected]+ '].dbo.Table1 
    WHERE [' [email protected]+ '].dbo.Table1.Column1 LIKE ''%execution%'' 
) IS NOT NULL 
    SET @testStatus = ''Test Passed'' 
ELSE 
    SET @testStatus = ''Test Failed'' 

INSERT INTO [Database1].dbo.Table3 (FileName, Version, Result, Date, TestNum, RepNum) 
VALUES (@name, @version, @testStatus, GETDATE(), @testid, @repid)' 
AS NVARCHAR(MAX)) 

EXECUTE (@query) 

FETCH NEXT FROM db_cursor INTO @dbname 

END 
CLOSE db_cursor 
DEALLOCATE db_cursor; 

문제는 내가 가진 동일한 일을 할 몇 가지 훨씬 더 복잡한 쿼리를 가지고있다 : 여기에 (IF 문 내부) 기본 쿼리를 사용하여 예입니다. 모든 것이 계획대로 진행되고 예상치 못한 결과가 나올 경우 예상했던 결과가 나옵니다. 여기에 내가 포함하기를 원하는보다 복잡한 질의 중 하나의 예가 있습니다 : (주목할 가치가 있습니다. 누군가가이 질의를 '수정'하여이 질문에 단순히 대답하기를 원하지 않습니다. 필자는 오류 메시지가) 사람이 해결하고 나는 오히려 나 자신을 수행하는 방법을 배울 것)

SELECT Table1.Column1, Table2.Column2, Table3.Column3, 
    Table3.Column4, Table3.Column5, Table3.Column6, 
    Table3.Column7 
FROM Table2 INNER JOIN 
    Table3 ON Table3.Column8 = Table2.id INNER JOIN 
    Table1 ON Table2.Column9 = Table1.id 
WHERE (Table3.Column5 = -1 AND Table3.Column7 > 0) OR 
    (Table3.Column5 = -1 AND Table3.Column6 > 0) OR 
    (Table3.Column5 > Table3.Column6 AND Table3.Column6 > 0) OR 
    (Table3.Column6 > Table3.Column7 AND Table3.Column7 > 0) 

내 if 문에이 쿼리에 때리고 때 (그리고 IS NOT NULL에 경우 조건을 변경합니다.

Msg 116, Level 16, State 1, Line 24 
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. 
Msg 116, Level 16, State 1, Line 24 
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. 

내게있어 궁극적 인 문제는 SQL을 충분히 이해하지 못했기 때문입니다.

편집 : 내가 작동하지 않는 코드를 표시하지 않았기 때문에 수정할 수 없으므로 여러 의견이 표시됩니다. 내가 제공 한 예제 코드가 충분히 구체적이지 않다는 것을 의미한다고 가정합니다.

하지만, 그게 내 질문의 요점을 놓치고있다. 나는 당신이 그 특별한 코드를 고치기를 원하지 않는다. 제 질문은 원래의 If/Else 코드가 특정 테이블에서 전체 테이블을 가져 오는 것과 같은 더 복잡한 SQL 쿼리를 처리 할 수 ​​없다는 것입니다.

아마도 내가 제공 한 예제 코드에 더 많은 컨텍스트를 제공하기 위해 아무 것도 반환하지 않는 쿼리 ("테스트 합격"조건)이거나 여러 행과 열이있는 테이블을 가져올 쿼리입니다 "Test Failed"조건). 나는 간단한 쿼리에 대해 작동하는 원래 쿼리를 가져 와서 단순히 "카운트 된"또는 다른 간단한 함수가 될 수없는 쿼리에 적용하는 방법에 대해 묻고있었습니다.

+1

오류와 마찬가지로 하나의 필드 만 허용되는 컨텍스트에서 여러 필드를 반환하는 하위 쿼리가 있습니다. 예 : 'select ... foo = (select field1, field2 from ....)'. 어떤 값을 'foo'와 비교해야합니까? 'field1'? 또는'field2'? 따라서 오류 - 당신은 모호성을 제거해야합니다 –

+0

나는 당신의 관점을 이해하지만, 우리는 SQL 문에 대한 코드를주지 않으면 SQL 문을 수정할 수 없습니다. 당신이 우리에게 오류 코드를주었습니다. 그러나 오류가있는 실제 SQL을 알려주십시오. – Hogan

+0

또한,'EXISTS()'가 어떻게 작동하는지에 대해서 읽을 필요가 있습니다. – Hogan

답변

-1

내가 보여주지 않은 코드는 말할 수 없지만 보여준 코드를 수행하는 더 좋은 방법을 지적 할 수 있습니다. 을 통해 다음과 같은 관심을 보이지 않는다

마크 이후
IF EXISTS (
    SELECT 1 
    FROM [' [email protected]+ '].dbo.Table1 
    WHERE [' [email protected]+ '].dbo.Table1.Column1 LIKE ''%execution%'') 
    SET @testStatus = ''Test Passed'' 
ELSE 
    SET @testStatus = ''Test Failed'' 
+0

글쎄, 동일하지 않습니다. 0의 카운트 (*)는 여전히 null이 아닙니다. 그러나 아마도 OP가 의도하는 바입니다. – Paparazzi

+0

@Paparazzi 카운트 (*)로 0을 얻을 수 있습니까? – Hogan

+0

그러면 카운트가 0이면 무엇이 반환 될까요? – Paparazzi

0

IF (
    SELECT COUNT(*) 
    FROM [' [email protected]+ '].dbo.Table1 
    WHERE [' [email protected]+ '].dbo.Table1.Column1 LIKE ''%execution%'' 
) IS NOT NULL 
    SET @testStatus = ''Test Passed'' 
ELSE 
SET @testStatus = ''Test Failed'' 

은 동일 : 당신은 신비 코드에 적용 할 때 아마 당신이 가지고있는 문제가 해결됩니다 여기에 귀하의 질문에 대한 답변입니다.

쿼리의 "복잡성"은 문제와 관련이 없습니다. 한 가지 이유로 오류가 발생하고 매우 간단한 쿼리에서도 같은 오류가 발생할 수 있습니다.

(당신이 언급 한 바와 같이)이 쿼리가 작동하는 다음 IF에서 하위 쿼리() 단일 값을 반환하기 때문에이 쿼리가 작동

IF (
    SELECT COUNT(*) 
    FROM [' [email protected]+ '].dbo.Table1 
    WHERE [' [email protected]+ '].dbo.Table1.Column1 LIKE ''%execution%'' 
) IS NOT NULL 
... 

이유입니다. 카운트. 하나의 행, 하나의 열. 하나의 값을 테스트하여 NULL인지 여부를 확인할 수 있으므로 아무런 문제가 없습니다.

이 쿼리는 작동하지 않을 것입니다 :

IF (
    SELECT Column1, Column2 
    FROM [' [email protected]+ '].dbo.Table1 
    WHERE [' [email protected]+ '].dbo.Table1.Column1 LIKE ''%execution%'' 
) IS NOT NULL 
... 

가 작동하지 않는 유일한 이유는 IF()의 하위 쿼리가 하나 이상의 열을 반환하므로이 쿼리의 결과가 NULL 비교 될 수 없다는 것입니다 . 어쩌면 당신의 마음 속에는 그것이 수행 될 수 있다고 생각하는 어떤 방법이있을 것입니다. (컬럼이 NULL이거나, 두 컬럼이 NULL 등입니다),하지만 당신에게 확신 할 수 없습니다. SQL 엔진은 결과 집합 (여러 열)을 NULL과 비교하는 방법을 알지 못합니다. SQL Server가 작동하는 방식이 아닙니다. 단일 스칼라 값과 NULL을 비교할 수만 있습니다.

Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

귀하의 "복잡한"쿼리 선택 목록에서 하나 이상의 열 (표현)이 있습니다 오류를 가지고 왜

. 이것이 유일한 이유입니다. 아무리 복잡한 쿼리라도, 하나의 열만 반환하는 경우 문제없이 IF() 문에서 사용할 수 있습니다.

복잡한 쿼리가 행을 반환하는지 아닌지 테스트해야하는 경우 작동하는 쿼리 에서처럼 열 목록을 COUNT (*)로 바꿀 수 있습니다.