亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 4105 | 回復(fù): 3
打印 上一主題 下一主題

SQL Server 2008 MERGE語(yǔ)法 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2011-03-09 19:50 |只看該作者 |倒序?yàn)g覽
根據(jù)與源表聯(lián)接的結(jié)果,對(duì)目標(biāo)表執(zhí)行插入、更新或刪除操作。例如,根據(jù)在另一個(gè)表中找到的差異在一個(gè)表中插入、更新或刪除行,可以對(duì)兩個(gè)表進(jìn)行同步。
http://space.itpub.net/?uid-1643 ... space-itemid-515891
語(yǔ)法

[ WITH <common_table_expression> [,...n] ]
MERGE
        [ TOP ( expression ) [ PERCENT ] ]
        [ INTO ] target_table [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ]
        USING <table_source>
        ON <merge_search_condition>
        [ WHEN MATCHED [ AND <clause_search_condition> ]
            THEN <merge_matched> ]
        [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]
            THEN <merge_not_matched> ]
        [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]
            THEN <merge_matched> ]
        [ <output_clause> ]
        [ OPTION ( <query_hint> [ ,...n ] ) ]   
;

<merge_hint>::=
{
    { [ <table_hint_limited> [ ,...n ] ]
    [ [ , ] INDEX ( index_val [ ,...n ] ) ] }
}

<table_source> ::=
{
        table_or_view_name [ [ AS ] table_alias ] [ <tablesample_clause> ]
            [ WITH ( table_hint [ [ , ]...n ] ) ]
    | rowset_function [ [ AS ] table_alias ]
            [ ( bulk_column_alias [ ,...n ] ) ]
    | user_defined_function [ [ AS ] table_alias ]
    | OPENXML <openxml_clause>
    | derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ]
    | <joined_table>
    | <pivoted_table>
    | <unpivoted_table>
}

<merge_search_condition> ::=
    <search_condition>

<merge_matched>::=
    { UPDATE SET <set_clause> | DELETE }

<set_clause>::=
SET
    { column_name = { expression | DEFAULT | NULL }
  | { udt_column_name.{ { property_name = expression
                                              | field_name = expression }
                                              | method_name ( argument [ ,...n ] ) }
     }
  | column_name { .WRITE ( expression , @Offset , @Length ) }
  | @variable = expression
  | @variable = column = expression
  | column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
  | @variable { += | -= | *= | /= | %= | &= | ^= | |= } expression
  | @variable = column { += | -= | *= | /= | %= | &= | ^= | |= } expression
  } [ ,...n ]

<merge_not_matched>::=
{
        INSERT [ ( column_list ) ]
            { VALUES ( values_list )
            | DEFAULT VALUES }
}

<clause_search_condition> ::=
    <search_condition>

<search condition> ::=
    { [ NOT ] <predicate> | ( <search_condition> ) }
    [ { AND | OR } [ NOT ] { <predicate> | ( <search_condition> ) } ]
[ ,...n ]

<predicate> ::=
    { expression { = | < > | ! = | > | > = | ! > | < | < = | ! < } expression
    | string_expression [ NOT ] LIKE string_expression
  [ ESCAPE 'escape_character' ]
    | expression [ NOT ] BETWEEN expression AND expression
    | expression IS [ NOT ] NULL
    | CONTAINS
    ( { column | * } , '< contains_search_condition >' )
    | FREETEXT ( { column | * } , 'freetext_string' )
    | expression [ NOT ] IN ( subquery | expression [ ,...n ] )
    | expression { = | < > | ! = | > | > = | ! > | < | < = | ! < }
  { ALL | SOME | ANY} ( subquery )
    | EXISTS ( subquery ) }

<output_clause>::=
{
    [ OUTPUT <dml_select_list> ]
        [ OUTPUT <dml_select_list> INTO { @table_variable | output_table }
            [ (column_list) ] ]
}

<dml_select_list>::=
        { <column_name> | scalar_expression }
                [ [AS] column_alias_identifier ] [ ,...n ]

<column_name> ::=
        { DELETED | INSERTED | from_table_name } . { * | column_name }
      | $action
參數(shù)
WITH <common_table_expression>
指定在 MERGE 語(yǔ)句作用域內(nèi)定義的臨時(shí)命名結(jié)果集或視圖,也稱為公用表表達(dá)式。該結(jié)果集派生自一個(gè)簡(jiǎn)單查詢,并由 MERGE 語(yǔ)句引用。有關(guān)詳細(xì)信息,請(qǐng)參閱 WITH common_table_expression (Transact-SQL)。

TOP ( expression ) [ PERCENT ]
指定受影響的行數(shù)或行百分比。expression 可以為行數(shù),也可以為行百分比。在 TOP 表達(dá)式中引用的行不是以任意順序排列的。有關(guān)詳細(xì)信息,請(qǐng)參閱 TOP (Transact-SQL)。

在聯(lián)接整個(gè)源表和整個(gè)目標(biāo)表并且刪除了不符合插入、更新或刪除操作條件的聯(lián)接行之后,應(yīng)用 TOP 子句。TOP 子句將聯(lián)接行的數(shù)量進(jìn)一步減少為指定值,并且以一種無(wú)序方式對(duì)其余聯(lián)接行應(yīng)用插入、更新或刪除操作。也就是說(shuō),在 WHEN 子句中定義的操作中,這些行是無(wú)序分布的。例如,如果指定 TOP (10),將會(huì)影響 10 行;在這些行中,可能會(huì)更新 7 行而插入 3 行,或者可能刪除 1 行、更新 5 行并且插入 4 行,等等。

由于 MERGE 語(yǔ)句對(duì)源表和目標(biāo)表都進(jìn)行完全表掃描,因此在使用 TOP 子句通過(guò)創(chuàng)建多個(gè)批處理來(lái)修改大型表時(shí),I/O 性能可能會(huì)受到影響。在這種情況下,一定要確保所有連續(xù)批處理都以新行作為處理目標(biāo)。有關(guān)詳細(xì)信息,請(qǐng)參閱優(yōu)化 MERGE 語(yǔ)句性能。

target_table
表或視圖,<table_source> 中的數(shù)據(jù)行將根據(jù) <clause_search_condition> 與該表或視圖進(jìn)行匹配。target_table 是由 MERGE 語(yǔ)句的 WHEN 子句指定的任何插入、更新或刪除操作的目標(biāo)。

如果 target_table 為視圖,則針對(duì)它的任何操作都必須滿足更新視圖所需的條件。有關(guān)詳細(xì)信息,請(qǐng)參閱通過(guò)視圖修改數(shù)據(jù)。target_table 不能是遠(yuǎn)程表。target_table 不能具有針對(duì)它定義的任何規(guī)則。

[ AS ] table_alias
用于引用表的替代名稱。

USING <table_source>
指定基于 <merge_search_condition> 與 target_table 中的數(shù)據(jù)行進(jìn)行匹配的數(shù)據(jù)源。此匹配的結(jié)果指出了要由 MERGE 語(yǔ)句的 WHEN 子句采取的操作。<table_source> 可以是一個(gè)遠(yuǎn)程表,或者是一個(gè)能夠訪問(wèn)遠(yuǎn)程表的派生表。

<table_source> 可以是一個(gè)使用 Transact-SQL 行構(gòu)造函數(shù)功能在單個(gè)語(yǔ)句中指定多個(gè)行的派生表。

有關(guān)此子句的語(yǔ)法和參數(shù)的詳細(xì)信息,請(qǐng)參閱 FROM (Transact-SQL)。

ON <merge_search_condition>
指定在 <table_source> 與 target_table 進(jìn)行聯(lián)接以確定它們的匹配位置時(shí)所遵循的條件。

注意:
重要的是,應(yīng)僅指定目標(biāo)表中用于匹配目的的列。也就是說(shuō),指定與源表中的對(duì)應(yīng)列進(jìn)行比較的目標(biāo)表列。不要嘗試通過(guò)在 ON 子句中篩選掉目標(biāo)表中的行來(lái)提高查詢性能,例如,指定 AND NOT target_table.column_x = value。這樣做可能會(huì)返回意外和不正確的結(jié)果。



WHEN MATCHED THEN <merge_matched>
指定 target_table 中與 <table_source> ON <merge_search_condition> 返回的行匹配并滿足所有其他搜索條件的所有行均應(yīng)根據(jù) <merge_matched> 子句進(jìn)行更新或刪除。MERGE 語(yǔ)句最多可以有兩個(gè) WHEN MATCHED 子句。如果指定了兩個(gè)子句,則第一個(gè)子句必須同時(shí)帶有一個(gè) AND <search_condition> 子句。對(duì)于任何給定的行,只有在未應(yīng)用第一個(gè) WHEN MATCHED 子句的情況下,才會(huì)應(yīng)用第二個(gè) WHEN MATCHED 子句。如果有兩個(gè) WHEN MATCHED 子句,那么其中的一個(gè)必須指定 UPDATE 操作,而另一個(gè)必須指定 DELETE 操作。如果在 <merge_matched> 子句中指定了 UPDATE,并且根據(jù) <merge_search_condition>,<table_source> 中的多個(gè)行與 target_table 中的某一行匹配,則 SQL Server 將返回錯(cuò)誤。MERGE 語(yǔ)句無(wú)法多次更新同一行,也無(wú)法更新和刪除同一行。

WHEN NOT MATCHED [ BY TARGET ] THEN <merge_not_matched>
指定對(duì)于 <table_source> ON <merge_search_condition> 返回的每一行,如果該行與 target_table 中的行不匹配,但是滿足其他搜索條件(如果存在),則在 target_table 中插入一行。要插入的值是由 <merge_not_matched> 子句指定的。MERGE 語(yǔ)句只能有一個(gè) WHEN NOT MATCHED 子句。

WHEN NOT MATCHED BY SOURCE THEN <merge_matched>
指定 target_table 中與 <table_source> ON <merge_search_condition> 返回的行不匹配但滿足所有其他搜索條件的所有行均應(yīng)根據(jù) <merge_matched> 子句進(jìn)行更新或刪除。

MERGE 語(yǔ)句最多可以有兩個(gè) WHEN NOT MATCHED BY SOURCE 子句。如果指定了兩個(gè)子句,則第一個(gè)子句必須同時(shí)帶有一個(gè) AND <clause_search_condition> 子句。對(duì)于任何給定的行,只有當(dāng)未應(yīng)用第一個(gè) WHEN NOT MATCHED BY SOURCE 子句時(shí)才會(huì)應(yīng)用第二個(gè)子句。如果有兩個(gè) WHEN NOT MATCHED BY SOURCE 子句,那么其中的一個(gè)必須指定 UPDATE 操作,而另一個(gè)必須指定 DELETE 操作。在 <clause_search_condition> 中只能引用目標(biāo)表中的列。

當(dāng) <table_source> 未返回任何行時(shí),無(wú)法訪問(wèn)源表中的列。如果 <merge_matched> 子句中指定的更新或刪除操作引用了源表中的列,將返回錯(cuò)誤 207(無(wú)效列名)。例如,由于無(wú)法訪問(wèn)源表中的 Col1,因此 WHEN NOT MATCHED BY SOURCE THEN UPDATE SET TargetTable.Col1 = SourceTable.Col1 子句可能導(dǎo)致該語(yǔ)句失敗。

AND <clause_search_condition>
指定任何有效的搜索條件。有關(guān)詳細(xì)信息,請(qǐng)參閱搜索條件 (Transact-SQL)。

<table_hint_limited>
為由 MERGE 語(yǔ)句執(zhí)行的每個(gè)插入、更新或刪除操作指定對(duì)目標(biāo)表應(yīng)用的一個(gè)或多個(gè)表提示。需要有 WITH 關(guān)鍵字和括號(hào)。

不允許使用 NOLOCK 和 READUNCOMMITTED。有關(guān)表提示的詳細(xì)信息,請(qǐng)參閱表提示 (Transact-SQL)。

對(duì)作為 INSERT 語(yǔ)句目標(biāo)的表指定 TABLOCK 提示與指定 TABLOCKX 提示具有相同的效果。對(duì)表采用排他鎖。如果指定了 FORCESEEK,會(huì)將其應(yīng)用于與源表聯(lián)接的目標(biāo)表的隱式實(shí)例。

注意:
指定帶有 WHEN NOT MATCHED [ BY TARGET ] THEN INSERT 的 READPAST 可能會(huì)導(dǎo)致違反 UNIQUE 約束的 INSERT 操作。



INDEX ( index_val [,...n ] )
指定目標(biāo)表上的一個(gè)或多個(gè)索引的名稱或 ID,以執(zhí)行與源表的隱式聯(lián)接。有關(guān)詳細(xì)信息,請(qǐng)參閱表提示 (Transact-SQL)。

<output_clause>
不按照任何特定順序?yàn)?target_table 中更新、插入或刪除的每一行返回一行。有關(guān)該子句的參數(shù)的詳細(xì)信息,請(qǐng)參閱 OUTPUT 子句 (Transact-SQL)。

$action
在 OUTPUT 子句中指定一個(gè) nvarchar(10) 類型的列,該子句為每一行返回以下三個(gè)值之一:'INSERT'、'UPDATE' 或 'DELETE',具體返回其中哪個(gè)值取決于對(duì)該行執(zhí)行的操作。

如果數(shù)據(jù)庫(kù)排序規(guī)則區(qū)分大小寫,則 $action 必須小寫。

OPTION ( <query_hint> [ ,...n ] )
指定使用優(yōu)化器提示來(lái)自定義數(shù)據(jù)庫(kù)引擎處理語(yǔ)句的方式。有關(guān)詳細(xì)信息,請(qǐng)參閱查詢提示 (Transact-SQL)。

<merge_matched>
指定更新或刪除操作,這些操作應(yīng)用于 target_table 中與 <table_source> ON <merge_search_condition> 返回的行不匹配但滿足所有其他搜索條件的所有行。

UPDATE SET <set_clause>
指定目標(biāo)表中要更新的列或變量名的列表,以及用于更新它們的值。

有關(guān)該子句的參數(shù)的詳細(xì)信息,請(qǐng)參閱 UPDATE (Transact-SQL)。不允許將變量設(shè)置為與列相同的值。

DELETE
指定刪除與 target_table 中的行匹配的行。


<merge_not_matched>
指定要插入到目標(biāo)表中的值。

( column_list )
要在其中插入數(shù)據(jù)的目標(biāo)表中的一列或多列的列表。必須使用單一部分名稱格式來(lái)指定這些列,否則 MERGE 語(yǔ)句將失敗。column_list 必須用圓括號(hào)括起來(lái),并用逗號(hào)進(jìn)行分隔。

VALUES ( values_list )
一個(gè)逗號(hào)分隔列表,其中包含常量、變量或者返回要插入到目標(biāo)表中的值的表達(dá)式。表達(dá)式不能包含 EXECUTE 語(yǔ)句。

DEFAULT VALUES
強(qiáng)制插入的行包含為每個(gè)列定義的默認(rèn)值。

有關(guān)該子句的詳細(xì)信息,請(qǐng)參閱 INSERT (Transact-SQL)。

<search condition>
指定用于指定 <merge_search_condition> 或 <clause_search_condition> 的搜索條件。有關(guān)該子句的參數(shù)的詳細(xì)信息,請(qǐng)參閱搜索條件 (Transact-SQL)。

備注
必須指定三個(gè) MATCHED 子句中的至少一個(gè)子句,但可以按任何順序指定。不能在同一個(gè) MATCHED 子句中多次更新一個(gè)變量。

由 MERGE 語(yǔ)句指定的目標(biāo)表中的任何插入、更新或刪除操作都受為它定義的任何約束的限制,包括任何級(jí)聯(lián)引用完整性約束。如果 IGNORE_DUP_KEY 對(duì)于目標(biāo)表中的任何唯一索引都設(shè)置為 ON,則 MERGE 將忽略此設(shè)置。

MERGE 語(yǔ)句需要一個(gè)分號(hào) ( 作為語(yǔ)句終止符。如果運(yùn)行沒(méi)有終止符的 MERGE 語(yǔ)句,將引發(fā)錯(cuò)誤 10713。

如果在 MERGE 之后使用,@@ROWCOUNT (Transact-SQL) 會(huì)返回為客戶端插入、更新和刪除的行的總數(shù)。

在數(shù)據(jù)庫(kù)兼容級(jí)別設(shè)置為 100 的情況下,MERGE 是完全保留的關(guān)鍵字。MERGE 語(yǔ)句在數(shù)據(jù)庫(kù)兼容級(jí)別為 90 和 100 的情況下也可用;但在數(shù)據(jù)庫(kù)兼容級(jí)別設(shè)置為 90 時(shí),此關(guān)鍵字不是完全保留的關(guān)鍵字。

觸發(fā)器的實(shí)現(xiàn)
對(duì)于在 MERGE 語(yǔ)句中指定的每個(gè)插入、更新或刪除操作,SQL Server 都會(huì)激發(fā)針對(duì)目標(biāo)表定義的任何對(duì)應(yīng)的 AFTER 觸發(fā)器,但不保證哪個(gè)操作最先或最后激發(fā)觸發(fā)器。為相同操作定義的觸發(fā)器會(huì)遵循您指定的順序進(jìn)行觸發(fā)。有關(guān)設(shè)置觸發(fā)器激發(fā)順序的詳細(xì)信息,請(qǐng)參閱指定第一個(gè)和最后一個(gè)觸發(fā)器。

對(duì)于由 MERGE 語(yǔ)句執(zhí)行的插入、更新或刪除操作,如果目標(biāo)表具有針對(duì)自己定義的已啟用 INSTEAD OF 觸發(fā)器,那么對(duì)于在 MERGE 語(yǔ)句中指定的所有操作,它都必須具有已啟用的 INSTEAD OF 觸發(fā)器。

如果對(duì) target_table 定義了任何 INSTEAD OF UPDATE 或 INSTEAD OF DELETE 觸發(fā)器,則不會(huì)執(zhí)行更新或刪除操作,而是會(huì)激發(fā)觸發(fā)器并相應(yīng)地填充 inserted 和 deleted 表。

如果對(duì) target_table 定義了任何 INSTEAD OF INSERT 觸發(fā)器,則不會(huì)執(zhí)行插入操作,而是會(huì)激發(fā)觸發(fā)器并相應(yīng)地填充 inserted 表。

權(quán)限
需要對(duì)源表的 SELECT 權(quán)限和對(duì)目標(biāo)表的 INSERT、UPDATE 或 DELETE 權(quán)限。有關(guān)其他信息,請(qǐng)參閱 SELECT、INSERT、UPDATE 和 DELETE 主題中的“權(quán)限”部分。

示例
A. 使用 MERGE 在單個(gè)語(yǔ)句中對(duì)表執(zhí)行 UPDATE 和 DELETE 操作
下面的示例使用 MERGE 根據(jù) SalesOrderDetail 表中已處理的訂單,每天更新 AdventureWorks 示例數(shù)據(jù)庫(kù)中的 ProductInventory 表。通過(guò)減去每天對(duì) SalesOrderDetail 表中的每種產(chǎn)品所下的訂單數(shù),更新 ProductInventory 表的 Quantity 列。如果某種產(chǎn)品的訂單數(shù)導(dǎo)致該產(chǎn)品的庫(kù)存量下降到 0 或更少,則會(huì)從 ProductInventory 表中刪除該產(chǎn)品對(duì)應(yīng)的行。


USE AdventureWorks;
GO
IF OBJECT_ID (N'Production.usp_UpdateInventory', N'P') IS NOT NULL DROP PROCEDURE Production.usp_UpdateInventory;
GO
CREATE PROCEDURE Production.usp_UpdateInventory
    @OrderDate datetime
AS
MERGE Production.ProductInventory AS target
USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod
    JOIN Sales.SalesOrderHeader AS soh
    ON sod.SalesOrderID = soh.SalesOrderID
    AND soh.OrderDate = @OrderDate
    GROUP BY ProductID) AS source (ProductID, OrderQty)
ON (target.ProductID = source.ProductID)
WHEN MATCHED AND target.Quantity - source.OrderQty <= 0
    THEN DELETE
WHEN MATCHED
    THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty,
                    target.ModifiedDate = GETDATE()
OUTPUT $action, Inserted.ProductID, Inserted.Quantity, Inserted.ModifiedDate, Deleted.ProductID,
    Deleted.Quantity, Deleted.ModifiedDate;
GO

EXECUTE Production.usp_UpdateInventory '20030501'
B. 借助派生的源表,使用 MERGE 對(duì)目標(biāo)表執(zhí)行 UPDATE 和 INSERT 操作
下面的示例使用 MERGE 以更新或插入行的方式來(lái)修改 SalesReason 表。當(dāng)源表中的 NewName 值與目標(biāo)表 (SalesReason) 的 Name 列中的值匹配時(shí),就會(huì)更新此目標(biāo)表中的 ReasonType 列。當(dāng) NewName 的值不匹配時(shí),就會(huì)將源行插入到目標(biāo)表中。此源表是一個(gè)派生表,它使用 Transact-SQL 行構(gòu)造函數(shù)功能指定源表的多個(gè)行。有關(guān)在派生表中使用行構(gòu)造函數(shù)的詳細(xì)信息,請(qǐng)參閱 FROM (Transact-SQL)。


USE AdventureWorks;
GO
MERGE INTO Sales.SalesReason AS Target
USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'), ('Internet', 'Promotion'))
       AS Source (NewName, NewReasonType)
ON Target.Name = Source.NewName
WHEN MATCHED THEN
UPDATE SET ReasonType = Source.NewReasonType
WHEN NOT MATCHED BY TARGET THEN
INSERT (Name, ReasonType) VALUES (NewName, NewReasonType)
OUTPUT $action, inserted.*, deleted.*;
C. 將 MERGE 語(yǔ)句的執(zhí)行結(jié)果插入到另一個(gè)表中
下例捕獲從 MERGE 語(yǔ)句的 OUTPUT 子句返回的數(shù)據(jù),并將該數(shù)據(jù)插入另一個(gè)表。MERGE 語(yǔ)句根據(jù)在 SalesOrderDetail 表中處理的訂單,更新 ProductInventory 表的 Quantity 列。本示例捕獲已更新的行,并將這些行插入用于跟蹤庫(kù)存變化的另一個(gè)表中。


USE AdventureWorks;
GO
CREATE TABLE Production.UpdatedInventory
    (ProductID INT NOT NULL, LocationID int, NewQty int, PreviousQty int,
     CONSTRAINT PK_Inventory PRIMARY KEY CLUSTERED (ProductID, LocationID));
GO
INSERT INTO Production.UpdatedInventory
SELECT ProductID, LocationID, NewQty, PreviousQty
FROM
(    MERGE Production.ProductInventory AS pi
     USING (SELECT ProductID, SUM(OrderQty)
            FROM Sales.SalesOrderDetail AS sod
            JOIN Sales.SalesOrderHeader AS soh
            ON sod.SalesOrderID = soh.SalesOrderID
            AND soh.OrderDate BETWEEN '20030701' AND '20030731'
            GROUP BY ProductID) AS src (ProductID, OrderQty)
     ON pi.ProductID = src.ProductID
    WHEN MATCHED AND pi.Quantity - src.OrderQty >= 0
        THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty
    WHEN MATCHED AND pi.Quantity - src.OrderQty <= 0
        THEN DELETE
    OUTPUT $action, Inserted.ProductID, Inserted.LocationID, Inserted.Quantity AS NewQty, Deleted.Quantity AS PreviousQty)
AS Changes (Action, ProductID, LocationID, NewQty, PreviousQty) WHERE Action = 'UPDATE';
GO

有關(guān)其他示例,請(qǐng)參閱使用 MERGE 插入、更新和刪除數(shù)據(jù)和優(yōu)化 MERGE 語(yǔ)句性能。

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2011-03-09 19:50 |只看該作者
Server 存儲(chǔ)過(guò)程簡(jiǎn)介與使用方法

      Sql Server的存儲(chǔ)過(guò)程是一個(gè)被命名的存儲(chǔ)在服務(wù)器上的Transacation-Sql語(yǔ)句集合,是封裝重復(fù)性工作的一種方法,它支持用戶聲明的變量、條件執(zhí)行和其他強(qiáng)大的編程功能。

      存儲(chǔ)過(guò)程相對(duì)于其他的數(shù)據(jù)庫(kù)訪問(wèn)方法有以下的優(yōu)點(diǎn):

            (1)重復(fù)使用。存儲(chǔ)過(guò)程可以重復(fù)使用,從而可以減少數(shù)據(jù)庫(kù)開(kāi)發(fā)人員的工作量。

            (2)提高性能。存儲(chǔ)過(guò)程在創(chuàng)建的時(shí)候就進(jìn)行了編譯,將來(lái)使用的時(shí)候不用再重新編譯。一般的SQL語(yǔ)句每執(zhí)行一次就需要編譯一次,所以使用存儲(chǔ)過(guò)程提高了效率。

            (3)減少網(wǎng)絡(luò)流量。存儲(chǔ)過(guò)程位于服務(wù)器上,調(diào)用的時(shí)候只需要傳遞存儲(chǔ)過(guò)程的名稱以及參數(shù)就可以了,因此降低了網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量。

            (4)安全性。參數(shù)化的存儲(chǔ)過(guò)程可以防止SQL注入式的攻擊,而且可以將Grant、Deny以及Revoke權(quán)限應(yīng)用于存儲(chǔ)過(guò)程。

      存儲(chǔ)過(guò)程一共分為了三類:用戶定義的存儲(chǔ)過(guò)程、擴(kuò)展存儲(chǔ)過(guò)程以及系統(tǒng)存儲(chǔ)過(guò)程。

      其中,用戶定義的存儲(chǔ)過(guò)程又分為Transaction-SQL和CLR兩種類型。

      Transaction-SQL 存儲(chǔ)過(guò)程是指保存的Transaction-SQL語(yǔ)句集合,可以接受和返回用戶提供的參數(shù)。

      CLR存儲(chǔ)過(guò)程是指對(duì).Net Framework公共語(yǔ)言運(yùn)行時(shí)(CLR)方法的引用,可以接受和返回用戶提供的參數(shù)。他們?cè)?Net Framework程序集中是作為類的公共靜態(tài)方法實(shí)現(xiàn)的。(本文就不作介紹了)

      創(chuàng)建存儲(chǔ)過(guò)程的語(yǔ)句如下:
Code
CREATE { PROC | PROCEDURE } [schema_name.] procedure_name [ ; number ]
    [ { @parameter [ type_schema_name. ] data_type }
        [ VARYING ] [ = default ] [ [ OUT [ PUT ]
    ] [ ,n ]
[ WITH <procedure_option> [ ,n ]
[ FOR REPLICATION ]
AS { <sql_statement> [;][ n ] | <method_specifier> }
[;]
<procedure_option> ::=
    [ ENCRYPTION ]
    [ RECOMPILE ]
    [ EXECUTE_AS_Clause ]

<sql_statement> ::=
{ [ BEGIN ] statements [ END ] }

<method_specifier> ::=
EXTERNAL NAME assembly_name.class_name.method_name



      [schema_name]: 代表的是存儲(chǔ)過(guò)程所屬的架構(gòu)的名稱

      例如:

            Create Schema yangyang8848      
            Go
            Create Proc yangyang8848.AllGoods
            As Select * From Master_Goods
            Go

            執(zhí)行:Exec AllGoods 發(fā)生錯(cuò)誤。

            執(zhí)行:Exec yangyang8848.AllGoods 正確執(zhí)行。

      [;Number]: 用于對(duì)同名過(guò)程進(jìn)行分組的可選整數(shù)。使用一個(gè) DROP PROCEDURE 語(yǔ)句可將這些分組過(guò)程一起刪除。

      例如:

            Create Proc S1 ;1
            AS
                   Select * From Master_Goods
            Go
            Create Proc S1 ;2
            As
                   Select * From Master_Location
            Go

            創(chuàng)建完畢了兩個(gè)存儲(chǔ)過(guò)程。它們?cè)谕粋(gè)組S1里,如果執(zhí)行Exec S1 則存儲(chǔ)過(guò)程默認(rèn)執(zhí)行 Exec S1 ;1 。如果我們想得到所有據(jù)點(diǎn)信息則需要執(zhí)行Exec S1 ;2。當(dāng)我們要?jiǎng)h除存儲(chǔ)過(guò)程的時(shí)候,只能執(zhí)行Drop Exec S1 則該組內(nèi)所有的存儲(chǔ)過(guò)程被刪除。

      [@ parameter]: 存儲(chǔ)過(guò)程中的參數(shù),除非將參數(shù)定義的時(shí)候有默認(rèn)值或者將參數(shù)設(shè)置為等于另一個(gè)參數(shù),否則用戶必須在調(diào)用存儲(chǔ)過(guò)程的時(shí)候?yàn)閰?shù)賦值。

      存儲(chǔ)過(guò)程最多有2100個(gè)參數(shù)。

      例如:

      Create Proc yangyang8848.OneGoods
      @GoodsCode varchar(10)
      As
             Select * From Master_Goods Where GoodsCode = @GoodsCode
      Go

      調(diào)用的代碼:

      Declare @Code varchar(10)
      Set @Code = '0004'
      Exec yangyang8848.OneGoods @Code

      在參數(shù)的后邊加入Output 表明該參數(shù)為輸出參數(shù)。

      Create Proc yangyang8848.OneGoods
      @GoodsCode2 varchar(10) output,@GoodsCode varchar(10) = '0011'
      As
             Select * From Master_Goods Where GoodsCode = @GoodsCode
             Set @GoodsCode2 = '0005'
      Go

      調(diào)用方法:
      Declare @VV2 varchar(10)
      Exec yangyang8848.OneGoods  @Code out

      注意:如果存儲(chǔ)過(guò)程的兩個(gè)參數(shù)一個(gè)有默認(rèn)值一個(gè)沒(méi)有,那么我們要把有默認(rèn)值得放在后邊,不然會(huì)出問(wèn)題哦~~

      細(xì)心的朋友,可能看到上邊的語(yǔ)句有一些不同,比如,存儲(chǔ)過(guò)程用的是output,而調(diào)用語(yǔ)句用的是out。我要告訴您,兩者是一樣的。

      
      [RECOMPILE]:指示數(shù)據(jù)庫(kù)引擎 不緩存該過(guò)程的計(jì)劃,該過(guò)程在運(yùn)行時(shí)編譯。如果指定了 FOR REPLICATION,則不能使用此選項(xiàng)。對(duì)于 CLR 存儲(chǔ)過(guò)程,不能指定 RECOMPILE。



      這個(gè)說(shuō)一個(gè)非常好用的函數(shù) OBJECT_ID :返回架構(gòu)范圍內(nèi)對(duì)象的數(shù)據(jù)庫(kù)對(duì)象標(biāo)識(shí)號(hào)。

      例如:我們創(chuàng)建存儲(chǔ)過(guò)程時(shí),可以如下寫代碼

      If Object_ID('yangyang8848.OneGoods') Is Not Null
             Drop Proc yangyang8848.OneGoods
      Go

      Create Proc yangyang8848.OneGoods
      @GoodsCode2 varchar(10) out,@GoodsCode varchar(10) = '0011'
      As
             Select * From Master_Goods Where GoodsCode = @GoodsCode
             Set @GoodsCode2 = '0005'
      Go

      針對(duì)于上邊的這個(gè)存儲(chǔ)過(guò)程,我們調(diào)用以下SQL查詢

      Select definition From sys.sql_modules
            Where object_id = Object_ID('yangyang8848.OneGoods');

      我們是可以查到結(jié)果的。

      可是如果我們對(duì)該存儲(chǔ)過(guò)程加入[ ENCRYPTION ] 那么你將無(wú)法看到任何結(jié)果

      If Object_ID('yangyang8848.OneGoods') Is Not Null
             Drop Proc yangyang8848.OneGoods
      Go

      Create Proc yangyang8848.OneGoods
      @GoodsCode2 varchar(10) out,@GoodsCode varchar(10) = '0011'

      With Encryption
      As
             Select * From Master_Goods Where GoodsCode = @GoodsCode
             Set @GoodsCode2 = '0005'
      Go

      然后我們查詢 sys.sql_modules 目錄視圖,將返回給你Null。

      然后我們執(zhí)行以下SQL: Exec sp_helptext 'yangyang8848.OneGoods'

      你將得到以下結(jié)果:The text for object 'yangyang8848.OneGoods' is encrypted.

      說(shuō)到這里你應(yīng)該明白了,參數(shù)[ ENCRYPTION ]:是一種加密的功能, 將 CREATE PROCEDURE 語(yǔ)句的原始文本轉(zhuǎn)換為模糊格式。模糊代碼的輸出在 SQL Server 2005 的任何目錄視圖中都不能直接顯示。對(duì)系統(tǒng)表或數(shù)據(jù)庫(kù)文件沒(méi)有訪問(wèn)權(quán)限的用戶不能檢索模糊文本。但是,可通過(guò) DAC 端口訪問(wèn)系統(tǒng)表的特權(quán)用戶或直接訪問(wèn)數(shù)據(jù)庫(kù)文件的特權(quán)用戶可使用此文本。此外,能夠向服務(wù)器進(jìn)程附加調(diào)試器的用戶可在運(yùn)行時(shí)從內(nèi)存中檢索已解密的過(guò)程。



      前兩天寫了一篇關(guān)于游標(biāo)的介紹文章 ,下邊寫一個(gè)例子,將游標(biāo)與存儲(chǔ)過(guò)程一起使用上:

      If Object_ID('dbo.GetMasterGoods') Is Not Null
            Drop Proc dbo.GetMasterGoods
      Go

      Create Proc GetMasterGoods
      @MyCursor Cursor Varying Output
      With Encryption
      As
             Set @MyCursor = Cursor
             For
                    Select GoodsCode,GoodsName From Master_Goods
      Open @MyCursor
      Go

      --下邊建立另外一個(gè)存儲(chǔ)過(guò)程,用于遍歷游標(biāo)輸出結(jié)果

      Create Proc GetAllGoodsIDAndName
      As

      Declare @GoodsCode varchar(1
      Declare @GoodsName nvarchar(20)
      Declare @MasterGoodsCursor Cursor
      Exec GetMasterGoods @MasterGoodsCursor out
      Fetch Next From @MasterGoodsCursor
      InTo @GoodsCode,@GoodsName
      While(@@Fetch_Status = 0)
      Begin
             Begin
                    Print @GoodsCode + ':' + @GoodsName
             End
             Fetch Next From @MasterGoodsCursor
             InTo @GoodsCode,@GoodsName
      End
      Close @MasterGoodsCursor
      Deallocate @MasterGoodsCursor
      Go

      最后執(zhí)行Exec GetAllGoodsIDAndName結(jié)果為以下內(nèi)容

      0003:品0003
      0004:品0004
      0005:123123
      0006:品0006
      0007:品0007
      0008:品0008
      0009:品0009
      0010:品0010
      0011:品0011
      0012:品0012
      0013:品0013
      0014:品0014


歡迎大家訪問(wèn)我的網(wǎng)站: http://www.shehui001.com/

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2011-03-09 19:53 |只看該作者
本帖最后由 liyihongcug 于 2011-03-10 13:18 編輯

http://msftdbprodsamples.codeplex.com/releases/view/4004
SQL Server 2008的實(shí)用小道具——merger
http://database.51cto.com  2010-09-06 14:14  無(wú)為是最高  博客園  我要評(píng)論(0)

    * 摘要:作為SQL Server 2008中推出的一個(gè)小道具merger,具備插入,刪除,修改一起來(lái)(適合數(shù)據(jù)的同步)的功能。讓我們一起來(lái)認(rèn)識(shí)它吧。
    * 標(biāo)簽:merger  SQL Server 2008
*

根據(jù)在另一個(gè)表中找到的差異在一個(gè)表中插入、更新或刪除行,可以對(duì)兩個(gè)表進(jìn)行同步。

A. 使用 MERGE 在單個(gè)語(yǔ)句中對(duì)表執(zhí)行 UPDATE 和 DELETE 操作

下面的示例使用 MERGE 根據(jù) SalesOrderDetail 表中已處理的訂單,每天更新 AdventureWorks 示例數(shù)據(jù)庫(kù)中的 ProductInventory 表。通過(guò)減去每天對(duì) SalesOrderDetail 表中的每種產(chǎn)品所下的訂單數(shù),更新 ProductInventory 表的 Quantity 列。如果某種產(chǎn)品的訂單數(shù)導(dǎo)致該產(chǎn)品的庫(kù)存量下降到 0 或更少,則會(huì)從 ProductInventory 表中刪除該產(chǎn)品對(duì)應(yīng)的行。

   1. USE AdventureWorks;  
   2. GO  
   3. IF OBJECT_ID (N'Production.usp_UpdateInventory', N'P')
   4. IS NOT NULL DROP PROCEDURE Production.usp_UpdateInventory;  
   5. GO  
   6. CREATE PROCEDURE Production.usp_UpdateInventory  
   7.     @OrderDate datetime  
   8. AS
   9. MERGE Production.ProductInventory AS target  
  10. USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod  
  11.     JOIN Sales.SalesOrderHeader AS soh  
  12.     ON sod.SalesOrderID = soh.SalesOrderID  
  13.     AND soh.OrderDate = @OrderDate  
  14.     GROUP BY ProductID) AS source (ProductID, OrderQty)  
  15. ON (target.ProductID = source.ProductID)  
  16. WHEN MATCHED AND target.Quantity - source.OrderQty <= 0  
  17.     THEN DELETE
  18. WHEN MATCHED  
  19.     THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty,  
  20.                     target.ModifiedDate = GETDATE()  
  21. OUTPUT $action, Inserted.ProductID, Inserted.Quantity, Inserted.ModifiedDate, Deleted.ProductID,  
  22.     Deleted.Quantity, Deleted.ModifiedDate;  
  23. GO  
  24.  
  25. EXECUTE Production.usp_UpdateInventory '20030501'

B. 借助派生的源表,使用 MERGE 對(duì)目標(biāo)表執(zhí)行 UPDATE 和 INSERT 操作

下面的示例使用 MERGE 以更新或插入行的方式來(lái)修改 SalesReason 表。當(dāng)源表中的 NewName 值與目標(biāo)表 (SalesReason) 的 Name 列中的值匹配時(shí),就會(huì)更新此目標(biāo)表中的 ReasonType 列。當(dāng) NewName 的值不匹配時(shí),就會(huì)將源行插入到目標(biāo)表中。此源表是一個(gè)派生表,它使用 Transact-SQL 行構(gòu)造函數(shù)功能指定源表的多個(gè)行。有關(guān)在派生表中使用行構(gòu)造函數(shù)的詳細(xì)信息,請(qǐng)參閱 FROM (Transact-SQL)。

   1. USE AdventureWorks;  
   2. GO  
   3. MERGE INTO Sales.SalesReason AS Target  
   4. USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'), ('Internet', 'Promotion'))  
   5.        AS Source (NewName, NewReasonType)  
   6. ON Target.Name = Source.NewName  
   7. WHEN MATCHED THEN
   8.  UPDATE SET ReasonType = Source.NewReasonType  
   9. WHEN NOT MATCHED BY TARGET THEN
  10.  INSERT (Name, ReasonType) VALUES (NewName, NewReasonType)  
  11. OUTPUT $action, inserted.*, deleted.*;

C. 將 MERGE 語(yǔ)句的執(zhí)行結(jié)果插入到另一個(gè)表中
下例捕獲從 MERGE 語(yǔ)句的 OUTPUT 子句返回的數(shù)據(jù),并將該數(shù)據(jù)插入另一個(gè)表。MERGE 語(yǔ)句根據(jù)在 SalesOrderDetail 表中處理的訂單,更新 ProductInventory 表的 Quantity 列。本示例捕獲已更新的行,并將這些行插入用于跟蹤庫(kù)存變化的另一個(gè)表中。

   1. USE AdventureWorks;  
   2. GO  
   3. CREATE TABLE Production.UpdatedInventory  
   4.     (ProductID INT NOT NULL, LocationID int, NewQty int, PreviousQty int,  
   5.      CONSTRAINT PK_Inventory PRIMARY KEY CLUSTERED (ProductID, LocationID));  
   6. GO  
   7. INSERT INTO Production.UpdatedInventory  
   8. SELECT ProductID, LocationID, NewQty, PreviousQty  
   9. FROM
  10. (    MERGE Production.ProductInventory AS pi  
  11.      USING (SELECT ProductID, SUM(OrderQty)  
  12.             FROM Sales.SalesOrderDetail AS sod  
  13.             JOIN Sales.SalesOrderHeader AS soh  
  14.             ON sod.SalesOrderID = soh.SalesOrderID  
  15.             AND soh.OrderDate BETWEEN '20030701' AND '20030731'
  16.             GROUP BY ProductID) AS src (ProductID, OrderQty)  
  17.      ON pi.ProductID = src.ProductID  
  18.     WHEN MATCHED AND pi.Quantity - src.OrderQty >= 0  
  19.         THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty  
  20.     WHEN MATCHED AND pi.Quantity - src.OrderQty <= 0  
  21.         THEN DELETE
  22.     OUTPUT $action, Inserted.ProductID, Inserted.LocationID, Inserted.Quantity AS NewQty, Deleted.Quantity AS PreviousQty)  
  23.  AS Changes (Action, ProductID, LocationID, NewQty, PreviousQty) WHERE Action = 'UPDATE';  
  24. GO

原文標(biāo)題:SQL SERVER 2008的幾個(gè)新東西:插入,刪除,修改一起來(lái)(適合數(shù)據(jù)的同步)-----merger

鏈接: http://www.cnblogs.com/buaaboyi/archive/2010/09/05/1818281.html

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2011-03-09 20:01 |只看該作者
ql server 2005中output用法解析

一、關(guān)于output子句

SQL Server 2005中的output子句,可以使你從修改語(yǔ)句(INSERT、UPDATE、DELETE)中將數(shù)據(jù)返回到表變量中。帶結(jié)果的 DML 的有用方案包括清除和存檔、消息處理應(yīng)用程序以及其他方案。這一新的 OUTPUT 子句的語(yǔ)法為:

OUTPUT INTO @table_variable



可以通過(guò)引用插入的表和刪除的表來(lái)訪問(wèn)被修改的行的舊/新映像,其方式與訪問(wèn)觸發(fā)器類似。在 INSERT 語(yǔ)句中,只能訪問(wèn)插入的表。在 DELETE 語(yǔ)句中,只能訪問(wèn)刪除的表。在 UPDATE 語(yǔ)句中,可以訪問(wèn)插入的表和刪除的表。

二、實(shí)例說(shuō)明

1、將 OUTPUT INTO 用于簡(jiǎn)單 INSERT 語(yǔ)句

以下示例將行插入 ScrapReason 表,并使用 OUTPUT 子句將語(yǔ)句的結(jié)果返回到 @MyTableVar table 變量。由于 ScrapReasonID 列使用 IDENTITY 屬性定義,因此未在 INSERT 語(yǔ)句中為該列指定一個(gè)值。但請(qǐng)注意,將在列 INSERTED.ScrapReasonID 內(nèi)的 OUTPUT 子句中返回由數(shù)據(jù)庫(kù)引擎 為該列生成的值。
代碼

use AdventureWorks
go
--定義一個(gè)表格變量
declare @mytablevar table( ScrapReasonID smallint,
Name1 varchar(50),
ModifiedDate datetime)
insert into Production.ScrapReason
output inserted.ScrapReasonID,inserted.[Name],inserted.ModifiedDate into @mytablevar
values ('operator error',getdate());
--顯示@mytablevar中的數(shù)據(jù)
select * from @mytablevar
--顯示Production.ScrapReason表中的數(shù)據(jù)
select * from Production.ScrapReason
go



以上語(yǔ)句中inserted是一個(gè)臨時(shí)表,當(dāng)我們往數(shù)據(jù)表中插入一條數(shù)據(jù)的時(shí)候數(shù)據(jù)庫(kù)會(huì)創(chuàng)建一個(gè)臨時(shí)表inserted保存插入的記錄;當(dāng)我們刪除某條記錄的時(shí)候,數(shù)據(jù)庫(kù)會(huì)創(chuàng)建一個(gè)臨時(shí)表deleted保存刪除的記錄。以上語(yǔ)句把新插入的數(shù)據(jù)填充到表變量@mytablevar中,然后輸出數(shù)據(jù),可以看到@mytablevar中的記錄和Production.ScrapReason中新插入的數(shù)據(jù)是一樣的。

2、 將 OUTPUT 用于 INSERT…SELECT 語(yǔ)句

以下示例創(chuàng)建 EmployeeSales 表,然后通過(guò)使用 SELECT 語(yǔ)句檢索源表中的數(shù)據(jù)將幾行插入該表。同時(shí),也計(jì)算了列 ProjectedSales 的值并將其插入該表中。OUTPUT 子句將 INSERT 語(yǔ)句的結(jié)果返回到執(zhí)行調(diào)用的應(yīng)用程序。最后的 SELECT 語(yǔ)句驗(yàn)證新 EmployeeSales 表的內(nèi)容是否與 OUTPUT 子句的結(jié)果匹配。
代碼

use AdventureWorks
go
if object_id('dbo.EmployeeSales','u') is not null
drop table dbo.EmployeeSales
go
create table dbo.EmployeeSales
(
EmployeeID nvarchar(11) not null,
LastName nvarchar(20) not null,
FirstName nvarchar(20) not null,
CurrentSales money not null,
ProjectedSales money not null

)
go
insert into dbo.EmployeeSales
output inserted.EmployeeID,inserted.LastName,inserted.FirstName,inserted.CurrentSales,inserted.ProjectedSales
SELECT e.EmployeeID, c.LastName, c.FirstName, sp.SalesYTD, sp.SalesYTD * 1.10
FROM HumanResources.Employee AS e
INNER JOIN Sales.SalesPerson AS sp
ON e.EmployeeID = sp.SalesPersonID
INNER JOIN Person.Contact AS c
ON e.ContactID = c.ContactID
WHERE e.EmployeeID LIKE '2%'
ORDER BY c.LastName, c.FirstName;
GO
SELECT EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales
FROM dbo.EmployeeSales;
GO



3、  將 OUTPUT 用于 DELETE 語(yǔ)句

以下示例將刪除 ShoppingCartItem 表中的所有行。子句 OUTPUT DELETED.* 指定 DELETE 語(yǔ)句的結(jié)果(即已刪除的行中的所有列)返回到執(zhí)行調(diào)用的應(yīng)用程序。后面的 SELECT 語(yǔ)句驗(yàn)證對(duì) ShoppingCartItem 表所執(zhí)行的刪除操作的結(jié)果。




USE AdventureWorks;
GO
DELETE Sales.ShoppingCartItem
OUTPUT DELETED.* ;

--驗(yàn)證表中所有數(shù)據(jù)都被刪除
SELECT COUNT(*) AS [Rows in Table] FROM Sales.ShoppingCartItem;
GO

4、 將 OUTPUT INTO 用于 UPDATE

下面的示例將 Employee 表中 VacationHours 列的前 10 行更新 25%。OUTPUT 子句將返回 VacationHours 值,該值在將列 DELETED.VacationHours 中的 UPDATE 語(yǔ)句和列 INSERTED.VacationHours 中的已更新值應(yīng)用于 @MyTableVar table 變量之前存在。
在它后面的兩個(gè) SELECT 語(yǔ)句返回 @MyTableVar 中的值以及 Employee 表中更新操作的結(jié)果。請(qǐng)注意,INSERTED.ModifiedDate 列中的結(jié)果與 Employee 表中的 ModifiedDate 列不具有相同的值。這是因?yàn)閷?duì) Employee 表定義了將 ModifiedDate 的值更新為當(dāng)前日期的 AFTER UPDATE 觸發(fā)器。但是,從 OUTPUT 中返回的列反映觸發(fā)器激發(fā)之前的數(shù)據(jù)。
代碼

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
EmpID int NOT NULL,
OldVacationHours int,
NewVacationHours int,
ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25
OUTPUT INSERTED.EmployeeID,
DELETED.VacationHours,
INSERTED.VacationHours,
INSERTED.ModifiedDate
INTO @MyTableVar;
--顯示@MyTableVar的值
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
--顯示插入表的值
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

5、 使用 OUTPUT INTO 返回表達(dá)式

以下示例在示例 D 的基礎(chǔ)上生成,方法是通過(guò)將 OUTPUT 子句中的表達(dá)式定義為已更新的 VacationHours 值與應(yīng)用更新之前的 VacationHours 值之間的差異。該表達(dá)式的值返回到列 VacationHoursDifference 中的 @MyTableVar table 變量。
代碼

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
EmpID int NOT NULL,
OldVacationHours int,
NewVacationHours int,
VacationHoursDifference int,
ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25
OUTPUT INSERTED.EmployeeID,
DELETED.VacationHours,
INSERTED.VacationHours,
INSERTED.VacationHours - DELETED.VacationHours,
INSERTED.ModifiedDate
INTO @MyTableVar;
--顯示表變量中的數(shù)據(jù)
SELECT EmpID, OldVacationHours, NewVacationHours,
VacationHoursDifference, ModifiedDate
FROM @MyTableVar;
GO
SELECT TOP (10) EmployeeID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

  

6、 在 UPDATE 語(yǔ)句中使用包含 from_table_name 的 OUTPUT INTO

以下示例使用指定的 ProductID 和 ScrapReasonID,針對(duì) WorkOrder 表中的所有工作順序更新 ScrapReasonID 列。OUTPUT INTO 子句返回所更新表 (WorkOrder) 中的值以及 Product 表中的值。在 FROM 子句中使用 Product 表來(lái)指定要更新的行。由于 WorkOrder 表具有對(duì)其定義的 AFTER UPDATE 觸發(fā)器,因此需要 INTO 關(guān)鍵字。
代碼

USE AdventureWorks;
GO
DECLARE @MyTestVar table (
OldScrapReasonID int NOT NULL,
NewScrapReasonID int NOT NULL,
WorkOrderID int NOT NULL,
ProductID int NOT NULL,
ProductName nvarchar(50)NOT NULL);
UPDATE Production.WorkOrder
SET ScrapReasonID = 4
OUTPUT DELETED.ScrapReasonID,
INSERTED.ScrapReasonID,
INSERTED.WorkOrderID,
INSERTED.ProductID,
p.Name
INTO @MyTestVar
FROM Production.WorkOrder AS wo
INNER JOIN Production.Product AS p
ON wo.ProductID = p.ProductID
AND wo.ScrapReasonID= 16
AND p.ProductID = 733;

SELECT OldScrapReasonID, NewScrapReasonID, WorkOrderID,
ProductID, ProductName
FROM @MyTestVar;
GO

7、在 DELETE 語(yǔ)句中使用包含 from_table_name 的 OUTPUT INTO

以下示例將按照在 DELETE 語(yǔ)句的 FROM 子句中所定義的搜索條件刪除 ProductProductPhoto 表中的行。OUTPUT 子句返回所刪除表(DELETED.ProductID、DELETED.ProductPhotoID)中的列以及 Product 表中的列。在 FROM 子句中使用該表來(lái)指定要?jiǎng)h除的行。


代碼

USE AdventureWorks
GO
DECLARE @MyTableVar table (
ProductID int NOT NULL,
ProductName nvarchar(50)NOT NULL,
ProductModelID int NOT NULL,
PhotoID int NOT NULL);

DELETE Production.ProductProductPhoto
OUTPUT DELETED.ProductID,
p.Name,
p.ProductModelID,
DELETED.ProductPhotoID
INTO @MyTableVar
FROM Production.ProductProductPhoto AS ph
JOIN Production.Product as p
ON ph.ProductID = p.ProductID
WHERE p.ProductModelID BETWEEN 120 and 130;

SELECT ProductID, ProductName, ProductModelID, PhotoID
FROM @MyTableVar
ORDER BY ProductModelID;
GO



8、 將 OUTPUT INTO 用于大型對(duì)象數(shù)據(jù)類型s  

以下示例使用 .WRITE 子句更新 Production.Document 表內(nèi) DocumentSummary 這一 nvarchar(max) 列中的部分值。通過(guò)指定替換單詞、現(xiàn)有數(shù)據(jù)中要替換的單詞的開(kāi)始位置(偏移量)以及要替換的字符數(shù)(長(zhǎng)度),將單詞 components 替換為單詞 features。此示例使用 OUTPUT 子句將 DocumentSummary 列的前像和后像返回到 @MyTableVar table 變量。請(qǐng)注意,將返回 DocumentSummary 列的全部前像和后像。

代碼

USE AdventureWorks;
GO
DECLARE @MyTableVar table (
DocumentID int NOT NULL,
SummaryBefore nvarchar(max),
SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT INSERTED.DocumentID,
DELETED.DocumentSummary,
INSERTED.DocumentSummary
INTO @MyTableVar
WHERE DocumentID = 3 ;
SELECT DocumentID, SummaryBefore, SummaryAfter
FROM @MyTableVar;
GO

9、 在 INSTEAD OF 觸發(fā)器中使用 OUTPUT

以下示例在觸發(fā)器中使用 OUTPUT 子句返回觸發(fā)器操作的結(jié)果。首先,創(chuàng)建一個(gè) ScrapReason 表的視圖,然后對(duì)該視圖定義 INSTEAD OF INSERT 觸發(fā)器,從而使用戶只修改基表的 Name 列。由于列 ScrapReasonID 是基表中的 IDENTITY 列,因此觸發(fā)器將忽略用戶提供的值。這允許數(shù)據(jù)庫(kù)引擎 自動(dòng)生成正確的值。同樣,用戶為 ModifiedDate 提供的值也被忽略并設(shè)置為正確的日期。OUTPUT 子句返回實(shí)際插入 ScrapReason 表中的值。

代碼

UUSE AdventureWorks;
GO
IF OBJECT_ID('dbo.vw_ScrapReason','V') IS NOT NULL
DROP VIEW dbo.vw_ScrapReason;
GO
CREATE VIEW dbo.vw_ScrapReason
AS (SELECT ScrapReasonID, Name, ModifiedDate
FROM Production.ScrapReason);
GO
CREATE TRIGGER dbo.io_ScrapReason
ON dbo.vw_ScrapReason
INSTEAD OF INSERT
AS
BEGIN
--ScrapReasonID is not specified in the list of columns to be inserted
--because it is an IDENTITY column.
INSERT INTO Production.ScrapReason (Name, ModifiedDate)
OUTPUT INSERTED.ScrapReasonID, INSERTED.Name,
INSERTED.ModifiedDate
SELECT Name, getdate()
FROM inserted;
END
GO
INSERT vw_ScrapReason (ScrapReasonID, Name, ModifiedDate)
VALUES (99, N'My scrap reason','20030404');
GO



10、  將 OUTPUT INTO 用于標(biāo)識(shí)列和計(jì)算列

下面的示例創(chuàng)建 EmployeeSales 表,然后使用 INSERT 語(yǔ)句向其中插入若干行,并使用 SELECT 語(yǔ)句從源表中檢索數(shù)據(jù)。EmployeeSales 表包含標(biāo)識(shí)列 (EmployeeID) 和計(jì)算列 (ProjectedSales)。由于這些值是在插入操作期間由數(shù)據(jù)庫(kù)引擎生成的,因此,不能在 @MyTableVar 中定義上述兩列。

代碼
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP