ใน SQL Server 2005 มีแนวคิดเกี่ยวกับการใช้งานครั้งเดียวหรือฟังก์ชันโลคัลที่ประกาศภายในสคริปต์ SQL หรือ Stored Procedure หรือไม่ ฉันต้องการลบล้างความซับซ้อนบางอย่างในสคริปต์ที่ฉันกำลังเขียน แต่จำเป็นต้องสามารถประกาศฟังก์ชันได้
แค่สงสัย.
ใน SQL Server 2005 มีแนวคิดเกี่ยวกับการใช้งานครั้งเดียวหรือฟังก์ชันโลคัลที่ประกาศภายในสคริปต์ SQL หรือ Stored Procedure หรือไม่ ฉันต้องการลบล้างความซับซ้อนบางอย่างในสคริปต์ที่ฉันกำลังเขียน แต่จำเป็นต้องสามารถประกาศฟังก์ชันได้
แค่สงสัย.
คำตอบ:
คุณสามารถโทรCREATE Function
ใกล้จุดเริ่มต้นของสคริปต์ของคุณและDROP Function
ใกล้จบ
คุณสามารถสร้างขั้นตอนการจัดเก็บชั่วคราวเช่น:
create procedure #mytemp as
begin
select getdate() into #mytemptable;
end
ในสคริปต์ SQL แต่ไม่ใช่ฟังก์ชัน คุณสามารถมีที่เก็บ proc ซึ่งส่งผลให้เกิดตารางชั่วคราวจากนั้นใช้ข้อมูลนั้นในสคริปต์ในภายหลัง ..
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 (เมนู Query -> โหมด 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 ด้วย
ด้านล่างนี้คือสิ่งที่ฉันเคยใช้ในอดีตเพื่อบรรลุความต้องการ Scalar UDF ใน MS SQL:
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
แนวทางนี้ซึ่งใช้ตัวแปรส่วนกลางสำหรับกระบวนการนี้ช่วยให้คุณใช้ประโยชน์จากฟังก์ชันได้ไม่เพียง แต่ในสคริปต์ของคุณเท่านั้น แต่ยังรวมถึงความต้องการ Dynamic SQL ของคุณด้วย