0

したがって、次のストアドプロシージャがあります。

CREATE PROCEDURE dbo.uspUpdateOrInsertDataObjectValue 
    @ParentDataObjectId INT,
    @DataObjectName NVARCHAR(256),
    @DataObjectValue NVARCHAR(256),
    @ForceInsert BIT,
    @ReturnDataObjectId INT OUT
WITH RECOMPILE
AS 
BEGIN
    if @ForceInsert = 0
    BEGIN
        UPDATE DataObjects SET Value=@DataObjectValue WHERE Name=@DataObjectName AND ParentDataObjectId=@ParentDataObjectId
    END
    if ( @ForceInsert = 1 ) OR ( @@ROWCOUNT = 0 )
    BEGIN
        --Spend time on the hierarchy id stuff only if we have to insert
        DECLARE @ParentTreeId HierarchyId
        DECLARE @LastChildTreeId HierarchyId
        SELECT @ParentTreeId = TreeId FROM DataObjects WHERE DataObjectId=@ParentDataObjectId
        SELECT @LastChildTreeId = MAX(TreeId) FROM DataObjects WHERE TreeId.GetAncestor(1)=@ParentTreeId
        INSERT INTO DataObjects ( Name, Value, ParentDataObjectId, TreeId ) VALUES ( @DataObjectName, @DataObjectValue, @ParentDataObjectId, @ParentTreeId.GetDescendant( @LastChildTreeId, NULL ) )
    END
    SELECT @ReturnDataObjectId = (SELECT TOP 1 DataObjectId FROM DataObjects WHERE Name=@DataObjectName AND ParentDataObjectId=@ParentDataObjectId ORDER BY DataObjectId DESC)
    RETURN 0
END
GO

`

そして、私はそれを次のように実行しています:

    int iParentDataObjectId = 1;
    int iDataObjectId = 0;
    SQLWCHAR    name[256];
    SQLWCHAR    value[256];

    _sntprintf_s( (wchar_t*)name, 256, _TRUNCATE, _T("%s"), pCDBDataObject->GetName() );
    _sntprintf_s( (wchar_t*)value, 256, _TRUNCATE, _T("%s"), pCDBDataObject->GetString() );

    result = SQLBindParameter( sqlStatementHandle, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &iParentDataObjectId, 0, NULL );
    result = SQLBindParameter( sqlStatementHandle, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WVARCHAR, 256, 0, name, 256, NULL );
    result = SQLBindParameter( sqlStatementHandle, 3, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WVARCHAR, 256, 0, value, 256, NULL );
    result = SQLBindParameter( sqlStatementHandle, 4, SQL_PARAM_INPUT, SQL_C_BIT, SQL_BIT, 1, 0, &forceInsert, 0, NULL );
    result = SQLBindParameter( sqlStatementHandle, 5, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &iDataObjectId, 0, NULL );

    result = SQLExecDirect( sqlStatementHandle, (SQLWCHAR*)_T("{CALL uspUpdateOrInsertDataObjectValue (?,?,?,?,?)}"), SQL_NTS );

'

ストアド プロシージャは正しく実行され、データベースを挿入または更新しますが、iDataObjectId は変更されません。

ただし、Sql Server Management Studio のスクリプトで次のように実行すると:

DECLARE @testval int
EXECUTE uspUpdateOrInsertDataObjectValue 1, 'Config', 'testasdfasdfasdfas', 1, @testval OUT
SELECT * from DataObjects where DataObjectId=@testval

出力値は @testval に割り当てられ、後続の select ステートメントは正常に機能します。

私は何が欠けていますか?

4

1 に答える 1

0

この例をより注意深く調べた後、答えを見つけました: http://technet.microsoft.com/en-us/library/ms403283.aspx

出力変数が設定される前に、SqlMoreResults を使用して query(call) の結果セットを消去する必要があります。私が期待していた動作ではありませんが、ドキュメントにはありました。

于 2014-04-21T15:43:14.447 に答える