0

VC++からストアドプロシージャを呼び出そうとしています。

ストアドプロシージャは次のようになります。

public static void SqlStoredProcedure2(string name, out byte[] backup)
{
    using (SqlConnection conn = new SqlConnection("context connection=true"))
    {
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        conn.Open();
        cmd.CommandText = "SELECT EmployeePhoto FROM [dbo].[DimEmployee] where FirstName like '%@name%'";
        SqlDataReader reader = null;
        reader = cmd.ExecuteReader();
        backup = null;
        while (reader.Read())
        {
            backup = (byte[])reader["EmployeePhoto"];
        }
        conn.Close();
    }
}

そして、c++コードは次のようになります。

RETCODE retcode = SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt);
retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 5, 0, "Alan", 0, &cbParm1);
unsigned char ptr[8000] = "";
cbParm2 = 8000;
retcode = SQLBindParameter(hstmt, 2, SQL_PARAM_OUTPUT, SQL_C_BINARY, SQL_VARBINARY, 0, 0, ptr, 0, &cbParm2);
retcode = SQLExecDirectA(hstmt, (UCHAR*)"{call SqlStoredProcedure2(?, ?)}", SQL_NTS);

返されたコードを確認してもエラーはありませんが、何も入りませんptrか?ここで何が問題になっていますか?

4

4 に答える 4

3

統合する前に、C#コードを単体テストすることをお勧めします。C#コードには多くの問題があります。1つ目は、C#コードで渡されたパラメーターがないことです。

リーダーを実行する前に、以下を追加してください。

cmd.Parameters.AddWithValue( "@name", name );

さらに、whileループは意味がなく(最後の画像を除くすべての画像を無視している)using、cmdに使用する必要があります。

補足として、最初と最後にワイルドカードを使用したこのような検索は非常に遅くなることに注意してください。

SQL Serverには、個別の機能として利用可能な全文検索があります。

于 2013-01-27T15:49:24.507 に答える
1

わかりました、問題を解決しました。これが正しい呼び出し方法です。

    SQLRETURN retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
    if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) )
    {
        printf("SQLAllocHandle(hstmt1) Failed\n\n");
        return;
    }

    retcode = SQLPrepareA(hstmt,(SQLCHAR*)"{call StoreProcedure2(?)}",SQL_NTS);

    SQLSMALLINT NumParams1, DataType1, DecimalDigits1, Nullable1;
    SQLULEN ParamSize1;
    unsigned char input1[50000] = "";
    SQLLEN inputlen1 = sizeof(input1);
    SQLINTEGER cbValue1 = sizeof(input1);//actual size of data in or out

    retcode = SQLDescribeParam(hstmt, 1, &DataType1, &ParamSize1, &DecimalDigits1, &Nullable1);
    retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_BINARY, DataType1, ParamSize1, DecimalDigits1, &input1, inputlen1 ,&cbValue1);

    retcode = SQLExecDirectA(hstmt, (UCHAR*)"{call StoreProcedure2(?)}", SQL_NTS);
    if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) 
    {
        printf("SQLExecDirect Failed\n\n");
        extract_error(hstmt,SQL_HANDLE_STMT);
        return;
    }
}
于 2013-02-09T15:21:05.347 に答える
0

「8000は私には死んだプレゼントのようです。」申し訳ありませんが、生成されたクエリが次のようになっているので、なぜ8000をそこに置いたのですか。

CREATE PROCEDURE [dbo].[SqlStoredProcedure2] @name [nvarchar](4000),
@backup [varbinary](8000)    OUTPUT
AS EXTERNAL NAME [Database1].[StoredProcedures].[SqlStoredProcedure2];

サイズを変えると変わると思いますが、そうはいきませんでした。

今、私はバッファのサイズを変更しようとしています。

于 2013-01-29T13:59:36.150 に答える
0

サイズの問題を解決しました。使用する必要があります

SqlFacet(MaxSize = -1)

パラメータなので、SQLストアドプロシージャは次のようになります

c#

[Microsoft.SqlServer.Server.SqlProcedure]
public static void SqlStoredProcedure2(string name, 
[SqlFacet(MaxSize = -1)]out byte[] backup)

生成されたクエリ

CREATE PROCEDURE [dbo].[SqlStoredProcedure2] @name [nvarchar](4000),
@backup [varbinary](MAX)     OUTPUT
AS EXTERNAL NAME [Database1].[StoredProcedures].[SqlStoredProcedure2];

私はまだc++の出力ptrに何も来ていない運が悪かった。

于 2013-02-02T11:43:03.053 に答える