[sql] 스크립트 또는 저장 프로 시저에서 일회용 함수를 만들 수 있습니까?

SQL Server 2005에는 SQL 스크립트 또는 저장 프로 시저 내에 선언 된 일회성 또는 로컬 함수의 개념이 있습니까? 내가 작성중인 스크립트의 복잡성을 추상화하고 싶지만 함수를 선언 할 수 있어야합니다.

그냥 궁금해.



답변

CREATE Function스크립트 시작 부분과 DROP Function끝 부분에 전화를 걸 수 있습니다 .


답변

다음과 같은 임시 저장 프로 시저를 만들 수 있습니다.

create procedure #mytemp as
begin
   select getdate() into #mytemptable;
end

SQL 스크립트에 있지만 함수는 아닙니다. 당신은 임시 테이블에 결과를 저장하는 proc을 가질 수 있으며, 그 정보를 나중에 스크립트에서 사용할 수 있습니다 ..


답변

공통 테이블 표현식 을 사용하면 select, insert, update 및 delete 문의 범위 내에서만 지속되는 본질적으로보기를 정의 할 수 있습니다. 무엇을해야하는지에 따라 매우 유용 할 수 있습니다.


답변

동적 SQL을 제안하는 것에 대해 비판을받을 수 있다는 것을 알고 있지만 때로는 좋은 솔루션입니다. 이를 고려하기 전에 보안 의미를 이해했는지 확인하십시오.

DECLARE @add_a_b_func nvarchar(4000) = N'SELECT @c = @a + @b;';
DECLARE @add_a_b_parm nvarchar(500) = N'@a int, @b int, @c int OUTPUT';

DECLARE @result int;
EXEC sp_executesql @add_a_b_func, @add_a_b_parm, 2, 3, @c = @result OUTPUT;
PRINT CONVERT(varchar, @result); -- prints '5'


답변

스크립트에는 더 많은 옵션과 합리적인 분해에 대한 더 나은 샷이 있습니다. SQLCMD 모드 (조회 메뉴-> SQLCMD 모드), 특히 : setvar 및 : r 명령을 살펴보십시오.

저장 프로 시저 내에서 옵션은 매우 제한적입니다. 프로 시저 본문을 사용하여 직접 함수를 정의 할 수 없습니다. 최선의 방법은 다음과 같이 동적 SQL을 사용하는 것입니다.

create proc DoStuff
as begin

  declare @sql nvarchar(max)

  /*
  define function here, within a string
  note the underscore prefix, a good convention for user-defined temporary objects
  */
  set @sql = '
    create function dbo._object_name_twopart (@object_id int)
    returns nvarchar(517) as
    begin
      return
        quotename(object_schema_name(@object_id))+N''.''+
        quotename(object_name(@object_id))
    end
  '

  /*
  create the function by executing the string, with a conditional object drop upfront
  */
  if object_id('dbo._object_name_twopart') is not null drop function _object_name_twopart
  exec (@sql)

  /*
  use the function in a query
  */
  select object_id, dbo._object_name_twopart(object_id)
  from sys.objects
  where type = 'U'

  /*
  clean up
  */
  drop function _object_name_twopart

end
go

이러한 것이 존재한다면 이것은 전역 임시 함수에 가깝습니다. 다른 사용자는 여전히 볼 수 있습니다. 연결의 @@ SPID를 추가하여 이름을 고유하게 만들 수 있지만 나머지 절차에서도 동적 SQL을 사용해야합니다.


답변

아래는 과거에 MS SQL에서 Scalar UDF에 대한 필요성을 달성하기 위해 사용한 것입니다.

IF OBJECT_ID('tempdb..##fn_Divide') IS NOT NULL DROP PROCEDURE ##fn_Divide
GO
CREATE PROCEDURE ##fn_Divide (@Numerator Real, @Denominator Real) AS
BEGIN
    SELECT Division =
        CASE WHEN @Denominator != 0 AND @Denominator is NOT NULL AND  @Numerator != 0 AND @Numerator is NOT NULL THEN
        @Numerator / @Denominator
        ELSE
            0
        END
    RETURN
END
GO

Exec ##fn_Divide 6,4

PROCEDURE에 전역 변수를 사용하는이 접근 방식을 사용하면 스크립트뿐만 아니라 동적 SQL 요구 사항에서도 함수를 사용할 수 있습니다.


답변