@@CONNECTIONS | @@TOTAL_ERRORS |
@@CPU_BUSY | @@TOTAL_READ |
@@IDLE | @@TOTAL_WRITE |
@@IO_BUSY | GETDATE |
@@MAX_CONNECTIONS | GETUTCDATE |
@@PACK_RECEIVED | NEWID |
@@PACK_SENT | RAND |
@@PACKET_ERRORS | TEXTPTR |
@@TIMETICKS |
盡管在用戶(hù)定義函數(shù)主體中不允許有不確定函數(shù),這些用戶(hù)定義函數(shù)在調(diào)用擴(kuò)展存儲(chǔ)過(guò)程時(shí)仍會(huì)產(chǎn)生副作用。
由于擴(kuò)展存儲(chǔ)過(guò)程會(huì)對(duì)數(shù)據(jù)庫(kù)產(chǎn)生副作用,因此調(diào)用擴(kuò)展存儲(chǔ)過(guò)程的函數(shù)是不確定的。當(dāng)用戶(hù)定義函數(shù)調(diào)用會(huì)對(duì)數(shù)據(jù)庫(kù)產(chǎn)生副作用的擴(kuò)展存儲(chǔ)過(guò)程時(shí),不要指望結(jié)果集保持一致或執(zhí)行函數(shù)。
從函數(shù)中調(diào)用擴(kuò)展存儲(chǔ)過(guò)程
從函數(shù)內(nèi)部調(diào)用時(shí)擴(kuò)展存儲(chǔ)過(guò)程無(wú)法向客戶(hù)端返回結(jié)果集。任何向客戶(hù)端返回結(jié)果集的 ODS API 都將返回 FAIL。擴(kuò)展存儲(chǔ)過(guò)程可以連接回 Microsoft® SQL Server™;但是,它不應(yīng)嘗試聯(lián)接與喚醒調(diào)用擴(kuò)展存儲(chǔ)過(guò)程的函數(shù)相同的事務(wù)。
與從批處理或存儲(chǔ)過(guò)程中喚醒調(diào)用相似,擴(kuò)展存儲(chǔ)過(guò)程在運(yùn)行 SQL Server 的 Windows® 安全帳戶(hù)的上下文中執(zhí)行。存儲(chǔ)過(guò)程的所有者在授予用戶(hù) EXECUTE 特權(quán)時(shí)應(yīng)考慮這一點(diǎn)。
函數(shù)調(diào)用
在可使用標(biāo)量表達(dá)式的位置可喚醒調(diào)用標(biāo)量值函數(shù),包括計(jì)算列和 CHECK 約束定義。當(dāng)喚醒調(diào)用標(biāo)量值函數(shù)時(shí),至少應(yīng)使用函數(shù)的兩部分名稱(chēng)。
[database_name.]owner_name.function_name ([argument_expr][,...])
如果用戶(hù)定義函數(shù)用于定義計(jì)算列,則該函數(shù)的確定性同樣決定了是否可在該計(jì)算列上創(chuàng)建索引。只有當(dāng)函數(shù)具有確定性時(shí),才可以在使用該函數(shù)的計(jì)算列上創(chuàng)建索引。如果在輸入相同的情況下函數(shù)始終返回相同的值,則該函數(shù)具有確定性。
可以使用由一部分組成的名稱(chēng)喚醒調(diào)用表值函數(shù)。
[database_name.][owner_name.]function_name ([argument_expr][,...])
對(duì)于 Microsoft® SQL Server™ 2000 中包含的系統(tǒng)表函數(shù),喚醒調(diào)用時(shí)需在函數(shù)名的前面加上前綴"::"。
SELECT *
FROM ::fn_helpcollations()
對(duì)于導(dǎo)致語(yǔ)句停止執(zhí)行然后從存儲(chǔ)過(guò)程中的下一語(yǔ)句繼續(xù)執(zhí)行的 Transact-SQL 錯(cuò)誤,在函數(shù)中的處理方式不同。在函數(shù)中,這類(lèi)錯(cuò)誤會(huì)導(dǎo)致函數(shù)停止執(zhí)行。這反過(guò)來(lái)使喚醒調(diào)用該函數(shù)的語(yǔ)句停止執(zhí)行。
權(quán)限
用戶(hù)應(yīng)具有執(zhí)行 CREATE FUNCTION 語(yǔ)句的 CREATE FUNCTION 權(quán)限。
CREATE FUNCTION 的權(quán)限默認(rèn)地授予 sysadmin 固定服務(wù)器角色和 db_owner 和 db_ddladmin 固定數(shù)據(jù)庫(kù)角色的成員。sysadmin 和 db_owner 的成員可用 GRANT 語(yǔ)句將 CREATE FUNCTION 權(quán)限授予其它登錄。
函數(shù)的所有者對(duì)其函數(shù)具有 EXECUTE 權(quán)限。其他用戶(hù)不具有 EXECUTE 權(quán)限,除非給他們授予了特定函數(shù)上的 EXECUTE 權(quán)限。
若要?jiǎng)?chuàng)建或更改在 CONSTRAINT、DEFAULT 子句或計(jì)算列定義中引用了用戶(hù)定義函數(shù)的表,用戶(hù)還必須對(duì)這些函數(shù)有 REFERENCES 權(quán)限。
示例
A. 計(jì)算 ISO 周的標(biāo)量值用戶(hù)定義函數(shù)
下例中,用戶(hù)定義函數(shù) ISOweek 取日期參數(shù)并計(jì)算 ISO 周數(shù)。為了正確計(jì)算該函數(shù),必須在調(diào)用該函數(shù)前喚醒調(diào)用 SET DATEFIRST 1。
CREATE FUNCTION ISOweek (@DATE datetime) RETURNS int AS BEGIN DECLARE @ISOweek int SET @ISOweek= DATEPART(wk,@DATE)+1 -DATEPART(wk,CAST(DATEPART(yy,@DATE) as CHAR(4))+'0104') --Special cases: Jan 1-3 may belong to the previous year IF (@ISOweek=0) SET @ISOweek=dbo.ISOweek(CAST(DATEPART(yy,@DATE)-1 AS CHAR(4))+'12'+ CAST(24+DATEPART(DAY,@DATE) AS CHAR(2)))+1 --Special case: Dec 29-31 may belong to the next year IF ((DATEPART(mm,@DATE)=12) AND ((DATEPART(dd,@DATE)-DATEPART(dw,@DATE))>= 28)) SET @ISOweek=1 RETURN(@ISOweek) END
下面是函數(shù)調(diào)用。注意 DATEFIRST 設(shè)置為 1。
SET DATEFIRST 1
SELECT master.dbo.ISOweek('12/26/1999') AS 'ISO Week'
下面是結(jié)果集。
ISO Week
----------------
52
B. 內(nèi)嵌表值函數(shù)
下例返回內(nèi)嵌表值函數(shù)。
USE pubs GO CREATE FUNCTION SalesByStore (@storeid varchar(30)) RETURNS TABLE AS RETURN (SELECT title, qty FROM sales s, titles t WHERE s.stor_id = @storeid and t.title_id = s.title_id)
C. 多語(yǔ)句表值函數(shù)
假設(shè)有一個(gè)表代表如下的層次關(guān)系:
CREATE TABLE employees (empid nchar(5) PRIMARY KEY, empname nvarchar(50), mgrid nchar(5) REFERENCES employees(empid), title nvarchar(30) )
表值函數(shù) fn_FindReports(InEmpID) 有一個(gè)給定的職員ID,它返回與所有直接或間接向給定職員報(bào)告的職員相對(duì)應(yīng)的表。該邏輯無(wú)法在單個(gè)查詢(xún)中表現(xiàn)出來(lái),不過(guò)可以實(shí)現(xiàn)為用戶(hù)定義函數(shù)。
CREATE FUNCTION fn_FindReports (@InEmpId nchar(5)) RETURNS @retFindReports TABLE (empid nchar(5) primary key, empname nvarchar(50) NOT NULL, mgrid nchar(5), title nvarchar(30)) /*Returns a result set that lists all the employees who report to given employee directly or indirectly.*/ AS BEGIN DECLARE @RowsAdded int -- table variable to hold accumulated results DECLARE @reports TABLE (empid nchar(5) primary key, empname nvarchar(50) NOT NULL, mgrid nchar(5), title nvarchar(30), processed tinyint default 0) -- initialize @Reports with direct reports of the given employee INSERT @reports SELECT empid, empname, mgrid, title, 0 FROM employees WHERE empid = @InEmpId SET @RowsAdded = @@rowcount -- While new employees were added in the previous iteration WHILE @RowsAdded > 0 BEGIN /*Mark all employee records whose direct reports are going to be found in this iteration with processed=1.*/ UPDATE @reports SET processed = 1 WHERE processed = 0 -- Insert employees who report to employees marked 1. INSERT @reports SELECT e.empid, e.empname, e.mgrid, e.title, 0 FROM employees e, @reports r WHERE e.mgrid=r.empid and e.mgrid > e.empid and r.processed = 1 SET @RowsAdded = @@rowcount /*Mark all employee records whose direct reports have been found in this iteration.*/ UPDATE @reports SET processed = 2 WHERE processed = 1 END -- copy to the result of the function the required columns INSERT @retFindReports SELECT empid, empname, mgrid, title FROM @reports RETURN END GO -- Example invocation SELECT * FROM fn_FindReports('11234') GO
標(biāo)簽:貸款群呼 濟(jì)寧 河源 新余 中衛(wèi) 金昌 宜春 黃山
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《CREATE FUNCTION sqlserver用戶(hù)定義函數(shù)》,本文關(guān)鍵詞 CREATE,FUNCTION,sqlserver,用戶(hù),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。