SQL Server 2005で、SQLスクリプトまたはストアドプロシージャの内部で宣言された、1回限りの使用、つまりローカル関数の概念はありますか?作成しているスクリプトの複雑さを抽象化したいのですが、関数を宣言できる必要があります。
ちょっと興味があるんだけど。
SQL Server 2005で、SQLスクリプトまたはストアドプロシージャの内部で宣言された、1回限りの使用、つまりローカル関数の概念はありますか?作成しているスクリプトの複雑さを抽象化したいのですが、関数を宣言できる必要があります。
ちょっと興味があるんだけど。
回答:
CREATE Function
スクリプトの最初とDROP Function
最後の近くで呼び出すことができます。
次のような一時ストアドプロシージャを作成できます。
create procedure #mytemp as
begin
select getdate() into #mytemptable;
end
SQLスクリプトでは使用できますが、関数では使用できません。ただし、結果を一時テーブルに格納して、後でスクリプトでその情報を使用することもできます。
BEGIN
キーワードを、と置き換えるEND
とキーワードをGO
。
共通テーブル式を使用すると、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でスカラー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のニーズでも関数を使用できます。