2011-03-31 85 views
1

我有一個簡單的腳本,基本上做了很多數據庫操作。現在我有一個需要升級的數據庫,我需要在同一個事務中包含一個函數的創建。是否有可能使用事務創建SQL SERVER函數

BEGIN TRY --Start the Try Block.. 

    BEGIN TRANSACTION -- Start the transaction.. 
     -- HERE I need to add one function like 
     IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FuctionTest]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT')) 
DROP FUNCTION [dbo].[FuctionTest] 
GO 
CREATE FUNCTION FuctionTest 
( 
    @inputVal int 
) 
RETURNS int 
AS 
BEGIN 
    RETURN (Select Id from [dbo].[test] where [email protected]) 
END 

     UPDATE MyChecking SET Amount = Amount - @Amount 

      WHERE AccountNum = @AccountNum 

     UPDATE MySavings SET Amount = Amount + @Amount 

      WHERE AccountNum = @AccountNum 

    COMMIT TRAN -- Transaction Success! 

END TRY 

BEGIN CATCH 

    IF @@TRANCOUNT > 0 

     ROLLBACK TRAN --RollBack in case of Error 

我將如何得到這份工作呢?我不想使用單獨的腳本來創建函數。

回答

5

是,使用EXEC('...'),如:

--list all functions named like '%test_function%', which will not find any 
SELECT [name] FROM sys.objects WHERE [name] like '%test_function%' 

--create a function named 'test_function1' 
exec ('create function [dbo].[test_function1] (@x int) returns varchar(50) as BEGIN return convert(varchar(50),@x)+''!'' END') 

begin transaction 

--create a function 'test_function2', which will be rolled back 
exec ('create function [dbo].[test_function2] (@x int) returns varchar(50) as BEGIN return convert(varchar(50),@x)+''!!!!'' END') 

rollback 

--show the functions named like '%test_function%' 
--which will only find 'test_function1', since 'test_function2' 
--was rolled back 
SELECT [name] FROM sys.objects WHERE [name] like '%test_function%' 

OUTPUT:

name 
----------------------- 

(0 row(s) affected) 

name 
------------------------- 
test_function1 

(1 row(s) affected) 

編輯顯示一個開始try塊....

BEGIN TRY 

    --list all functions named like '%test_function%', which will not find any 
    SELECT [name] FROM sys.objects WHERE [name] like '%test_function%' 

    --create a function named 'test_function1' 
    exec ('create function [dbo].[test_function1] (@x int) returns varchar(50) as BEGIN return convert(varchar(50),@x)+''!'' END') 

    begin transaction 

    --create a function 'test_function2', which will be rolled back 
    exec ('create function [dbo].[test_function2] (@x int) returns varchar(50) as BEGIN return convert(varchar(50),@x)+''!!!!'' END') 

    RAISERROR('force catch!',16,1) --send control to the BEGIN CATCH block 

    --should never get here 
    COMMIT 

END TRY 
BEGIN CATCH 

    IF XACT_STATE()!=0 
    BEGIN 
     ROLLBACK TRANSACTION 
    END 
    PRINT CASE WHEN ERROR_NUMBER() IS NOT NULL THEN 'Msg '+CONVERT(varchar(30),ERROR_NUMBER()) ELSE '' END+CASE WHEN ERROR_SEVERITY() IS NOT NULL THEN ', Level '+CONVERT(varchar(30),ERROR_SEVERITY()) ELSE '' END+CASE WHEN ERROR_STATE() IS NOT NULL THEN ', State '+CONVERT(varchar(30),ERROR_STATE()) ELSE '' END+CASE WHEN ERROR_PROCEDURE() IS NOT NULL THEN ', Procedure '+ERROR_PROCEDURE() ELSE '' END+CASE WHEN ERROR_LINE() IS NOT NULL THEN ', Line '+CONVERT(varchar(30),ERROR_LINE()) ELSE '' END+CASE WHEN ERROR_MESSAGE() IS NOT NULL THEN ', '+ERROR_MESSAGE() ELSE '' END 
END CATCH 


--show the functions named like '%test_function%' 
--which will only find 'test_function1', since 'test_function2' 
--was rolled back 
SELECT [name] FROM sys.objects WHERE [name] like '%test_function%' 

OUTPUT:

name 
--------------------------------------------------- 

(0 row(s) affected) 

Msg 50000, Level 16, State 1, Line 14, force catch! 
name 
--------------------------------------------------- 
test_function1 

(1 row(s) affected) 
+0

RacerX嗨, 你能使用相同的腳本,如果存在它上面的try/catch塊即try/catch塊將包含事務塊,然後我需要在事務內該腳本。 謝謝, 小吃 – 2011-03-31 16:44:18

+0

RacerX:好像你的方法將取決於無需創建...足夠權限的用戶是這樣嗎? – 2011-04-01 16:21:11

+0

是的。使用'EXEC'不會以任何方式繞過這個要求。 – 2011-04-01 16:40:12

相關問題