Question

So I have the following stored procedure:

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

`

And I'm executing it like this:

    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 );

'

The stored procedure executes properly and inserts or updates the database but iDataObjectId never changes.

However when I execute it like this in a script in Sql Server Management Studio:

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

the output value is assigned to @testval and the subsequent select statement works just fine.

What am I missing?

Was it helpful?

Solution

I found the answer after a more careful examination of this example: http://technet.microsoft.com/en-us/library/ms403283.aspx

You need to clean out the result sets of the query(call) with SqlMoreResults before the output variables get set. Not the behavior I would have expected but it was right there in the documentation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top