2

다음 저장 프로시 저는 지정된 테이블의 열을 동적으로 결정하고 null이 아닌 모든 열을 반환하지만 동적 프로 시저를 테스트 할 때 결과가 돌아 왔음에도 불구하고 저장된 proc은 null을 반환합니다 자체 쿼리를 동적 쿼리 결과를 올바르게 처리 오전?동적 쿼리에서 출력을 반환하지 않는 SQL Server 2008 저장 프로 시저

CREATE PROCEDURE [dbo].[spGetTables] 
(
    @TableName varchar(255) 
,@ParamOut varchar(2000) OUTPUT 
) 
AS 

declare @CommaString varchar(max) 
set @CommaString = '' 

Declare @col varchar(255), @cmd nvarchar(max) 
declare @colName varchar(2000) 
SET @colName = '' 

DECLARE getinfo cursor for 
SELECT c.name FROM sys.tables t JOIN sys.columns c ON t.Object_ID = c.Object_ID 
WHERE t.Name = @TableName 

OPEN getinfo 

FETCH NEXT FROM getinfo into @col 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    SELECT @cmd = 'IF NOT EXISTS (SELECT top 1 * FROM [' + @TableName + '] WHERE [' + @col + '] IS NULL or len([' + @col + ']) < 1) BEGIN select ''' + @col + ','' END' 

    exec sp_executesql @cmd, N'@Result varchar(max) out', @ParamOut out 

    set @ParamOut = @ParamOut + @CommaString 

    FETCH NEXT FROM getinfo into @col 
END 

PRINT 'Result: '[email protected] 

CLOSE getinfo 
DEALLOCATE getinfo 
RETURN 0 

답변

2
빈 문자열로 NULL을 기반으로 값을 대체하려고 문제를 일으키는 이 하나의 절차를 변경하고 다시 시도

:

CREATE PROCEDURE [dbo].[spGetTables] 
(
    @TableName varchar(255) 
,@ParamOut varchar(2000) OUTPUT 
) 
AS 

declare @CommaString varchar(max) 
set @CommaString = '' 

Declare @col varchar(255), @cmd nvarchar(max) 
declare @colName varchar(2000) 
SET @colName = '' 

DECLARE getinfo cursor for 
SELECT c.name FROM sys.tables t JOIN sys.columns c ON t.Object_ID = c.Object_ID 
WHERE t.Name = @TableName 

OPEN getinfo 

FETCH NEXT FROM getinfo into @col 

DECLARE @TempParamOut varchar(2000) = ''; 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    SELECT @cmd = ' IF NOT EXISTS (SELECT top 1 * FROM [' + @TableName + '] WHERE [' + @col + '] IS NULL or len([' + @col + ']) < 1) BEGIN select @Result= ''' + @col + ','' END' 

    exec sp_executesql @cmd, N'@Result varchar(max) out', @TempParamOut out 

    set @ParamOut = ISNULL(@ParamOut,'') + ISNULL(@TempParamOut,'') + @CommaString; 
    set @TempParamOut = ''; 
    FETCH NEXT FROM getinfo into @col 
END 


CLOSE getinfo 
DEALLOCATE getinfo 
RETURN 0 

을 당신이의 할당 된 값을 필요로하는 동적 T-SQL 성명에서 변수에. 또한 때때로이 출력 값은 NULL 일 수 있지만 STRING + NULLNULL과 같습니다. 중간 결과를 저장하기 위해 버퍼 변수 @TempParamOut을 추가했습니다. 동적 T-SQL 문을 실행할 때마다 @ParamOut 변수를 사용하고 해당 값을 덮어 씁니다. 그래서 연결은 전혀 수행되지 않습니다.

+0

, 작동하는 것 같다에

그것을 변경 @ gotqn! – Joelster

+0

@gotqn, NULL을 찾으면 @TempParamOut의 값을 유지하므로 @ParamOut을 설정 한 후에 지울 필요가 있습니다. set @ParamOut = ISNULL (@ParamOut, '') + ISNULL (@TempParamOut, '') + @CommaString; \t @TempParamOut = ''; –

+0

@ShaunGroenewald 감사합니다. 나는 그것을 바꿨다. – gotqn

2

NULL 기반 추가 (더하기 (+) 기호 사용)가있는 경우 일반적으로 출력으로 NULL이 표시됩니다. , 이하의 절차,

  1. 인쇄 동적으로 생성 된 SQL 문을 극복하고 어떤 필드보기 위해
  2. 가 ('')
1

@gotqn은 이미 실수를 발견했습니다. 출력 변수에 아무 것도 지정하지 않았습니다. - 더 나은 '[' + name + ']' 대신에 이것을 사용

DECLARE 
    @sql VARCHAR(MAX), 
    @TableName VARCHAR(100) = 'dbo.MyTable' 


SELECT @sql = 'SELECT STUFF(''''' + 
    (
     SELECT 
      ' 
      +ISNULL(
        MIN(CASE WHEN t.' + QUOTENAME (c.name) + ' IS NOT NULL AND LEN(t.' + QUOTENAME (c.name) + ') >= 1 THEN '', ' + QUOTENAME (c.name) + ''' ELSE '''' END) 
        , '''')' 
     FROM sys.columns c 
     WHERE c.[object_id] = t.[object_id] 
     ORDER BY c.column_id 
     FOR XML PATH(''), TYPE 
    ).value('.', 'VARCHAR(MAX)') + ', 1, 1, '''') FROM ' 
    + QUOTENAME(OBJECT_SCHEMA_NAME(t.object_id)) + '.' + QUOTENAME(t.name) + ' as t' 
FROM sys.tables t 
WHERE t.object_id = object_id(@TableName, 'U') 

print @sql 

EXEC (@sql) 

EXEC ('select top 10 * from ' + @TableName) 

QUOTENAME 기능 여기 :

그러나 여기 커서없이 하나의 소스 테이블 스캔과 다른 접근 방식입니다. 그리고 물론 객체들은 다른 schema을 가질 수 있으므로 이름으로 필터링하는 것이 안전한 해결책이 아닐 수도 있습니다.

1

@gotqn 님의 답변이 해제되었습니다.

실행했을 때 결과가 제대로 정렬되지 않고 행 수가 너무 적습니다. 이 중 일부는 예를 들어 들판의 쓰레기 값 때문이었습니다. ""그리고 검사는 조금 벗어났다. 덕분에 IF 대신 어디 NULL NOT EXISTS와 렌>가 널 열에 대한 이전의 null 이외의 열을 반복하는 작은 결함 이외의 0

ALTER PROCEDURE [dbo].[spGetTables] 
(
    @TableName varchar(255) 
,@ParamOut varchar(2000) OUTPUT 
) 
AS 

declare @CommaString varchar(max) 
set @CommaString = '' 

Declare @col varchar(255), @cmd nvarchar(max) 
declare @colName varchar(2000) 
SET @colName = '' 

DECLARE getinfo cursor for 
SELECT c.name FROM sys.tables t JOIN sys.columns c ON t.Object_ID = c.Object_ID 
WHERE t.Name = @TableName 

OPEN getinfo 

FETCH NEXT FROM getinfo into @col 

DECLARE @TempParamOut varchar(2000) = ''; 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    SELECT @cmd = 'IF EXISTS (SELECT top 1 * FROM [' + @TableName + '] WHERE [' + @col + '] IS NOT NULL and len(LTRIM(RTRIM(REPLACE(REPLACE(REPLACE([' + @col + '], CHAR(10), ''''), CHAR(13), ''''), CHAR(9), '''')))) > 0) BEGIN select @Result=''' + @col + ','' END' 

    exec sp_executesql @cmd, N'@Result varchar(max) out', @TempParamOut out 

    set @ParamOut = ISNULL(@ParamOut,'') + ISNULL(@TempParamOut,'') + @CommaString; 
    set @TempParamOut = ''; 

    FETCH NEXT FROM getinfo into @col 
END 

CLOSE getinfo 
DEALLOCATE getinfo 
RETURN 0