2012-12-18 4 views
0

나는 totalCount 열에 대한 WhereClause테이블의 각 행에 대해 동적 SQL을 실행하는 방법은 무엇입니까?

DECLARE @UserGroups TABLE (WhereClause nvarchar(1000), totalCount int) 

테이블은 WhereClause에 대한 몇 가지 값으로 생성 된 이름이 열하지만 아무도을 포함하는 테이블이 있습니다.

WhereClause의 예는 "FirstName is null"입니다.

기본적으로 테이블의 각 행에 대해 다른 테이블 (사용자)에서 COUNT (*)를 계산하고 위의 표에 totalCount을 설정해야합니다. 나는 SQL 함수를 만들고 함수 내에서 간부 sp_executesql을 호출 시도

SELECT UG.WhereClause, U.TotalCount 
FROM @UserGroups as UG 
OUTER APPLY (SELECT COUNT(*) as 'TotalCount' FROM [Users] WHERE UG.WhereClause) 
) U 

하지만 지원되지 않는 아래

이 작동하지 않습니다.

CREATE FUNCTION [dbo].[fn_UserGroupCount] 
( 
    @whereClause as NVARCHAR(1000) 
) 
RETURNS @returnValue TABLE (TotalCount INT) 
AS 
BEGIN 
    DECLARE @stmt nvarchar(1500) 

    SET @stmt = 'SELECT COUNT(*) FROM [dbo].[Users] 
    WHERE ' + @whereClause 

    Exec sp_executesql @stmt 

RETURN 
END 

SELECT * FROM [dbo].[fn_UserGroupCount]('Subject is null') 

언급 한대로 내 @UserGroups 테이블을 채울 수 있습니까?

감사

+0

실제로 아이디어는 좋은 보이지만이 방법은 각 행에 대해 ** 실행해야 할 것이다 D-SQL로 처리 과부하에 추가됩니다 **. 당신은 당신의 요구 사항을위한 또 다른 대안을 찾을 수 있습니까? – Rachcha

답변

1

이 시도, 당신은 (@UserGroups 그래서 난 #UserGroups로 대체 작동하지 않습니다) 그것에 도달 할 수 있도록 동적 SQL에 대한 임시 테이블을 사용해야합니다 :

CREATE TABLE #UserGroups (WhereClause nvarchar(1000), totalCount int) 
INSERT #UserGroups VALUES ('FirstName IS NULL', NULL) 
INSERT #UserGroups VALUES ('FirstName IS NOT NULL', NULL) 

DECLARE @sql VARCHAR(8000) = STUFF(
(
SELECT ';UPDATE #UserGroups SET totalCount = (SELECT COUNT(*) FROM [Users] WHERE ' + WhereClause + ') WHERE WhereClause = ''' + WhereClause + '''' 
FROM #UserGroups 
FOR XML PATH('') 
), 1, 1, '') 

PRINT @sql 
EXEC(@sql) 

SELECT * 
FROM #UserGroups 

DROP TABLE #UserGroups 

그러나 WhereClause에 따옴표가 포함되어 있으면 FirstName LIKE 'Joe'과 같은 문제가 발생할 수 있습니다.

+0

고맙지 만 스레드로부터 안전하지 않으므로 사용할 수 없습니다. 2 회의 통화가 동시에 이루어지면 임시 테이블과 함께 실패합니다. –

+0

당신을 진심으로 환영합니다. 약간의 오류가 있습니까? 오류 텍스트는 무엇을 말하고 있습니까? 이 코드를 응용 프로그램에서 호출합니까? –

+1

다른 문제가 있었지만이 답변을 통해 문제 해결에 필요한 단서를 얻을 수있었습니다.감사합니다 :) –

0

커서를 사용하여 @whereclause의 select count (*)가 포함 된 업데이트 문을 포함하는 문자열을 작성합니다. 그런 다음이를 실행하여 업데이트를 수행 할 수 있습니다. 아래 SQLFiddle 참조 : where 절은 또한에 작은 따옴표를 가지고 어디

업데이트] 지금 작동하는 곳 조항에 아포스트로피

SQL Fiddle

MS SQL 서버 2008 스키마 설정 :

create table users 
(
    userid int primary key identity, 
    name varchar(50), 
    subject varchar(50) null 
); 

INSERT INTO users (name, subject) 
VALUES 
    ('Fred', 'Maths'), 
    ('Bill', null), 
    ('Helen', 'English'), 
    ('O''Keefe', 'Maths'); 

쿼리 1 :

DECLARE @WhereClause nvarchar(1000) 
DECLARE @stmt nvarchar(1500) = '' 

CREATE TABLE #UserGroups (WhereClause nvarchar(1000), totalCount int) 
INSERT #UserGroups VALUES ('Subject IS NULL', NULL) 
INSERT #UserGroups VALUES ('Subject IS NOT NULL', NULL) 
INSERT #UserGroups VALUES ('Subject =''Maths''', NULL) 
INSERT #UserGroups VALUES ('name =''O''''Keefe''', NULL) 

DECLARE cur CURSOR FOR 
    SELECT WhereClause FROM #UserGroups 

OPEN cur 

FETCH cur INTO @WhereClause 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    SELECT @stmt = @stmt + 
     'UPDATE #UserGroups ' + 
     'SET totalCount = ' + 
     '(SELECT COUNT(*) FROM users WHERE ' + @WhereClause + ') ' + 
     'WHERE WhereClause = ''' + REPLACE(@WhereClause, '''', '''''') + ''';' 
    FETCH cur INTO @WhereClause 
END 

CLOSE cur 
DEALLOCATE cur 

--select @stmt 
exec(@stmt) 

SELECT * 
FROM #UserGroups 

DROP TABLE #UserGroups 

Results 16,:

|   WHERECLAUSE | TOTALCOUNT | 
------------------------------------ 
|  Subject IS NULL |   1 | 
| Subject IS NOT NULL |   3 | 
| Subject ='Maths' |   2 | 
| name ='O''Keefe' |   1 | 
+0

'WhereClause'가 따옴표를 포함 할 수 있다면 그 동적 SQL은 안전하지 않습니다. 'COUNT()'질의는 안전하지만'WhereClause' 컬럼과의 비교는 유효하지 않습니다. –

+0

@Damien_The_Unbeliever가 업데이트되어 where 절에서 따옴표를 처리합니다. 비교 값에 따옴표가있는 절과 같은 문제가 여전히있을 수 있습니다. name = 'O''Keefe' –

+0

@TheLight 아포스트로피 및 텍스트 필드 비교가있는 모든 where 절에 대해 이제 작동합니다. –

관련 문제