如何在同一时间使用游标并使用范围标识?

时间:2017-08-17 17:11:22

标签: xml sql-server-2008 tsql xpath xquery

我有一个像这样的XML文件:

<FormActions>
    <FormAction>
        <IsPassParams>1</IsPassParams>
        <IsSendEmail>1</IsSendEmail>
        <FormActionID>0</FormActionID>
        <ActionName>Account Full Info. SSRS 24</ActionName>
        <ActionPath>C:/</ActionPath>
        <FormID>536</FormID>
        <SeqNo>1</SeqNo>
        <ProgramType>5</ProgramType>
        <CreatedUserID xsi:nil="true" />
        <CreatedDate xsi:nil="true" />
        <UpdatedUserID xsi:nil="true" />
        <UpdatedDate xsi:nil="true" />
        <SendVariableID>--here
            <int>9</int>--variableID
            <int>11</int>--variableID
        </SendVariableID>--here
    </FormAction>
    <FormAction>
        <IsPassParams>1</IsPassParams>
        <IsSendEmail>1</IsSendEmail>
        <FormActionID>0</FormActionID>
        <ActionName>Account Full Info. SSRS 26</ActionName>
        <ActionPath>C:/</ActionPath>
        <FormID>516</FormID>
        <SeqNo>1</SeqNo>
        <ProgramType>5</ProgramType>
        <CreatedUserID xsi:nil="true" />
        <CreatedDate xsi:nil="true" />
        <UpdatedUserID xsi:nil="true" />
        <UpdatedDate xsi:nil="true" />
        <SendVariableID> --here
            <int>8</int> --variableID
            <int>279</int> --variableID
        </SendVariableID> --here
    </FormAction>
</FormActions>

我有一张桌子

VariableActionID | VariableID

我想添加VariableActionID,并在另一个表中创建FormActionID,插入此数据。

我用过这个但是没用。

ALTER PROCEDURE [dbo].[frm_Update_frmFormAction]
    @ModuleID INT,
    @FormID INT,
    @XMLID INT,
    @UserID BIGINT
AS
BEGIN TRY
    --1. Delete existing
    DELETE ffa
    FROM frm_Form_Action ffa (NOLOCK)
    WHERE ffa.FormID = @FormID;

    DECLARE @int INT, @formActionID INT;

    --2. Insert new Form Action
    INSERT INTO frm_Form_Action(ActionName, ActionPath, FormID, SeqNo, 
                                ProgramType, IsPassParams, isSendEmail,
                                CreatedDate, CreatedUserID)
        SELECT 
            ActionName = x.ActionName, ActionPath = x.ActionPath,
            FormID = @FormID, SeqNo = x.SeqNo,
            ProgramType = x.ProgramType, IsPassParams = x.IsPassParams,
            IsSendEmail = x.IsSendEmail,
            CreatedDate = dbo.ufn_Get_UTCDate(), CreatedUserID = @UserID
        FROM
            OPENXML(@XMLID, '/Form/FormActions/FormAction', 2)
        WITH
            (ActionName NVARCHAR(255),
             ActionPath NVARCHAR(2000),
             FormID INT,
             ProgramType SMALLINT,
             IsPassParams SMALLINT,
             IsSendEmail SMALLINT,
             SeqNo SMALLINT) x;

    DECLARE MY_CURSOR CURSOR LOCAL STATIC FOR
        SELECT x.[int]
        FROM OPENXML(@XMLID, '/Form/FormActions/FormAction/SendVariableID', 2)
             WITH ([int] INT) x;

    OPEN MY_CURSOR;

    FETCH NEXT FROM MY_CURSOR INTO @int;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        @formActionID = scope_identity();

        IF EXISTS (SELECT TOP 1 1 FROM dbo.frm_Form_Action 
                   WHERE ProgramType = 5)
        BEGIN
            INSERT INTO dbo.frm_Form_Action_Variables (VariableActionID, VariableID)
                SELECT @formActionID, @int
        END;
    END;

    CLOSE MY_CURSOR;
    DEALLOCATE MY_CURSOR;

我使用游标从FormActionID表中获取frm_Form_Action值并将其插入VariableActionID表中的frm_Form_Action_Variable内,但每次尝试此操作时,都会正确插入值在frm_Form_Action中,但它只在frm_Action_Variable表中插入1条记录。

2 个答案:

答案 0 :(得分:3)

抱歉,我不了解您的需求,但有一点可以肯定:

FROM OPENXML与相应的SP准备和删除文档已经过时,不应再使用(很少有例外)。而是使用适当的methods the XML data type provides

这是以表格格式获取所有数据的一种方法。希望这会有所帮助:

DECLARE @xml XML=
N'<FormActions xmlns:xsi="dummy">
    <FormAction>
        <IsPassParams>1</IsPassParams>
        <IsSendEmail>1</IsSendEmail>
        <FormActionID>0</FormActionID>
        <ActionName>Account Full Info. SSRS 24</ActionName>
        <ActionPath>C:/</ActionPath>
        <FormID>536</FormID>
        <SeqNo>1</SeqNo>
        <ProgramType>5</ProgramType>
        <CreatedUserID xsi:nil="true" />
        <CreatedDate xsi:nil="true" />
        <UpdatedUserID xsi:nil="true" />
        <UpdatedDate xsi:nil="true" />
        <SendVariableID>--here
            <int>9</int>--variableID
            <int>11</int>--variableID
        </SendVariableID>--here
    </FormAction>
    <FormAction>
        <IsPassParams>1</IsPassParams>
        <IsSendEmail>1</IsSendEmail>
        <FormActionID>0</FormActionID>
        <ActionName>Account Full Info. SSRS 26</ActionName>
        <ActionPath>C:/</ActionPath>
        <FormID>516</FormID>
        <SeqNo>1</SeqNo>
        <ProgramType>5</ProgramType>
        <CreatedUserID xsi:nil="true" />
        <CreatedDate xsi:nil="true" />
        <UpdatedUserID xsi:nil="true" />
        <UpdatedDate xsi:nil="true" />
        <SendVariableID> --here
            <int>8</int> --variableID
            <int>279</int> --variableID
        </SendVariableID> --here
    </FormAction>
</FormActions>';

- 查询

SELECT fa.value(N'(ActionName/text())[1]',N'nvarchar(max)') AS ActionName
      ,fa.value(N'(ActionPath/text())[1]',N'nvarchar(max)') AS ActionPath
      ,fa.value(N'(FormID/text())[1]',N'int') AS FormId
      --ommited some values
      ,fa.value(N'(CreatedUserID/text())[1]',N'int') AS CreatedUserID --returns NULL, no "text()"
      --ommited some values
      ,vInt.value('text()[1]','int') AS vInt
FROM @xml.nodes(N'/FormActions/FormAction') AS A(fa)
OUTER APPLY A.fa.nodes(N'SendVariableID/int') AS B(vInt);

结果:

+----------------------------+------------+--------+---------------+------+
| ActionName                 | ActionPath | FormId | CreatedUserID | vInt |
+----------------------------+------------+--------+---------------+------+
| Account Full Info. SSRS 24 | C:/        | 536    | NULL          | 9    |
+----------------------------+------------+--------+---------------+------+
| Account Full Info. SSRS 24 | C:/        | 536    | NULL          | 11   |
+----------------------------+------------+--------+---------------+------+
| Account Full Info. SSRS 26 | C:/        | 516    | NULL          | 8    |
+----------------------------+------------+--------+---------------+------+
| Account Full Info. SSRS 26 | C:/        | 516    | NULL          | 279  |
+----------------------------+------------+--------+---------------+------+

更新(取自您的 - 重复 - 跟进问题)

尝试此查询:

SELECT fa.value(N'(ActionName/text())[1]',N'nvarchar(max)') AS ActionName
      ,fa.value(N'(ActionPath/text())[1]',N'nvarchar(max)') AS ActionPath
      ,fa.value(N'(FormID/text())[1]',N'int') AS FormId
      --ommited some values
      ,fa.value(N'(CreatedUserID/text())[1]',N'int') AS CreatedUserID --returns NULL, no "text()"
      --ommited some values
      ,vInt.value('text()[1]','int') AS vInt
      ,DENSE_RANK() OVER(ORDER BY fa.value(N'(FormID/text())[1]',N'int'))
FROM @xml.nodes(N'/FormActions/FormAction') AS A(fa)
OUTER APPLY A.fa.nodes(N'SendVariableID/int') AS B(vInt);

我添加了DENSE_RANK() - 来电来获取您的VariableActionId

这个查询的结果集是一个表或者至少:可以很容易地用来填充或创建一个表。

最简单的方法是使用

之类的东西
INSERT INTO YourTable(Col1,Col2,...)
SELECT Col1,Col2,... FROM ...

这会立即将此结果集插入到您的表中。

答案 1 :(得分:1)

尝试根据需要调整此代码,在输出表中更改主键的名称

inserted.YOUR PK 




declare @inserted as table (sequence int) 

INSERT INTO frm_Form_Action
(
    ActionName,
    ActionPath,
    FormID,
    SeqNo,
    ProgramType,
    IsPassParams,
    isSendEmail,
    CreatedDate,
    CreatedUserID
)
output 
inserted.YOUR PK 
into @inserted
SELECT ActionName = x.ActionName,
       ActionPath = x.ActionPath,
       FormID = @FormID,
       SeqNo = x.SeqNo,
       ProgramType = x.ProgramType,
       IsPassParams = x.IsPassParams,
       IsSendEmail = x.IsSendEmail,
       CreatedDate = dbo.ufn_Get_UTCDate(),
       CreatedUserID = @UserID
FROM
    OPENXML(@XMLID, '/Form/FormActions/FormAction', 2)
    WITH
    (
        ActionName NVARCHAR(255),
        ActionPath NVARCHAR(2000),
        FormID INT,
        ProgramType SMALLINT,
        IsPassParams SMALLINT,
        IsSendEmail SMALLINT,
        SeqNo SMALLINT
    ) x

;with cte_xml as (
select 
row.value('.','int') VariableID
from
  @xml.nodes('/FormActions/FormAction/SendVariableID') t(SendVariableID)
  cross apply SendVariableID.nodes('int') y(row)
 ),
  cte_inserted as (
 SELECT 
    sequence as VariableActionID
 FROM 
    @inserted
)
INSERT INTO dbo.frm_Form_Action_Variables
        (
            VariableActionID,
            VariableID
        )
 select distinct 
  VariableActionID
 , VariableID
 from cte_xml cross join cte_inserted