문제

나는이 질문을 말로 표면으로 말할 것입니다. 나는 그것이 해결 될 수 없다고 생각합니다. 또한 해결 방법이 있습니다.이를 수행하기 위해 출력으로 저장된 절차를 만들 수 있습니다. 함수를 사용 하여이 체크섬이 필요한 섹션을 코딩하는 것이 더 쉽습니다.

이 코드는이 코드가 작동하지 않습니다 Exec SP_ExecuteSQL @SQL 전화. 기능에서 동적 SQL을 실행하는 방법을 아는 사람이 있습니까? (그리고 다시 한번, 나는 그것이 가능하다고 생각하지 않습니다. 그러나 그것이 있다면, 나는 그것을 주변에가는 방법을 알고 싶습니다!)

Create Function Get_Checksum
(
    @DatabaseName      varchar(100),
    @TableName         varchar(100)
)
RETURNS FLOAT
AS
BEGIN

 Declare @SQL        nvarchar(4000)
 Declare @ColumnName varchar(100)
 Declare @i          int
 Declare @Checksum   float
 Declare @intColumns table (idRecord int identity(1,1), ColumnName varchar(255))
 Declare @CS         table (MyCheckSum bigint)

 Set @SQL = 
        'Insert Into @IntColumns(ColumnName)' + Char(13) + 
        'Select Column_Name' + Char(13) +
        'From   ' + @DatabaseName + '.Information_Schema.Columns (NOLOCK)' + Char(13) +
        'Where  Table_Name = ''' + @TableName + '''' + Char(13) +
        '       and Data_Type = ''int''' 

 -- print @SQL

 exec sp_executeSql @SQL

 Set @SQL = 
        'Insert Into @CS(MyChecksum)' + Char(13) + 
        'Select '

 Set @i = 1

 While Exists(
       Select 1
       From   @IntColumns
       Where  IdRecord = @i)
 begin
       Select @ColumnName = ColumnName
       From   @IntColumns
       Where  IdRecord = @i

       Set @SQL = @SQL + Char(13) + 
            CASE WHEN @i = 1 THEN 
                 '    Sum(Cast(IsNull(' + @ColumnName + ',0) as bigint))'
                 ELSE
                 '    + Sum(Cast(IsNull(' + @ColumnName + ',0) as bigint))'
            END

       Set @i = @i + 1
 end

 Set @SQL = @SQL + Char(13) + 
      'From ' + @DatabaseName + '..' + @TableName + ' (NOLOCK)'

 -- print @SQL

 exec sp_executeSql @SQL

 Set @Checksum = (Select Top 1 MyChecksum From @CS)

 Return isnull(@Checksum,0)

END
GO
도움이 되었습니까?

해결책

SQL Server가 기능을 결정 론으로 취급함에 따라 "일반적으로"수행 할 수 없습니다. 즉, 주어진 입력 세트의 경우 항상 동일한 출력을 반환해야합니다. 저장된 절차 또는 동적 SQL은 의존하는 테이블과 같은 외부 상태를 변경할 수 있기 때문에 결정적이지 않을 수 있습니다.

SQL 서버 기능이 항상 결정적이라는 점을 감안할 때, 향후 코드를 지원 해야하는 사람에게 상당히 큰 혼란을 야기 할 수 있기 때문에 미래의 유지 보수 관점에서이를 우회하는 것은 나쁜 생각이 될 것입니다.

다른 팁

다음은 해결책입니다

Solution 1:그런 다음 기능에서 동적 문자열을 반환하십시오

Declare @SQLStr varchar(max) 
DECLARE @tmptable table (<columns>)
set @SQLStr=dbo.function(<parameters>)
insert into @tmptable
Exec (@SQLStr)

select * from @tmptable

Solution 2:매개 변수를 전달하여 중첩 기능을 호출하십시오.

모든 승무원 번거 로움과 보안 문제로 확장 저장된 절차를 호출하여이 문제를 해결할 수 있습니다.

http://deciperinfosys.wordpress.com/2008/07/16/udf-limitations-in-sql-server/

http://deciperinfosys.wordpress.com/2007/02/27/using-getdate-in-a-udf/

기능은 쿼리 최적화기와 잘 작동해야하기 때문에 몇 가지 제한이 있습니다. 이 링크 UDF의 깊이의 한계를 논의하는 기사를 나타냅니다.

답장에 감사드립니다.

Ron : FYI, 사용하면 오류가 발생합니다.

나는 원래 의도 한 것을하지 않는 것이 최선의 해결책이라는 데 동의합니다. 나는 다른 길을 가기로 결정했습니다. 나의 두 가지 선택은 사용하는 것이었다 sum(cast(BINARY_CHECKSUM(*) as float)) 또는 저장 프로 시저의 출력 매개 변수. 각각의 단위 테스트 속도 후, 나는 함께 가기로 결정했다. sum(cast(BINARY_CHECKSUM(*) as float)) 각 테이블의 데이터에 대해 비슷한 체크섬 값을 얻으려면.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top