C# 调用存储过程时未检索到数据

C# 调用存储过程时未检索到数据,c#,c++,C#,C++,我试图从VC++调用一个存储过程 以下是存储过程的外观: public static void SqlStoredProcedure2(string name, out byte[] backup) { using (SqlConnection conn = new SqlConnection("context connection=true")) { SqlCommand cmd = new SqlCommand(); cmd.Connectio

我试图从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();
    }
}
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);

和C++代码看起来类似:

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();
    }
}
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
中没有任何内容?这里出了什么问题?

我建议您在集成之前对C代码进行单元测试。你的C代码有很多问题。第一个是你没有在C代码中传递参数

在执行读取器之前添加以下内容

cmd.Parameters.AddWithValue( "@name", name );
此外,while循环没有任何意义(您忽略了除最后一张图片以外的所有图片),您应该对cmd使用
using

需要注意的是,像这样的搜索在开始和结束时都带有通配符,速度会非常慢


SQL Server有一个单独的全文搜索功能。

我建议您在集成之前对C代码进行单元测试。你的C代码有很多问题。第一个是你没有在C代码中传递参数

在执行读取器之前添加以下内容

cmd.Parameters.AddWithValue( "@name", name );
此外,while循环没有任何意义(您忽略了除最后一张图片以外的所有图片),您应该对cmd使用
using

需要注意的是,像这样的搜索在开始和结束时都带有通配符,速度会非常慢

SQL Server提供了一个单独的全文搜索功能。

“8000对我来说似乎是一个致命的赠品。”对此表示抱歉, 为什么我把8000放在那里,因为生成的查询是这样的

CREATE PROCEDURE [dbo].[SqlStoredProcedure2] @name [nvarchar](4000),
@backup [varbinary](8000)    OUTPUT
AS EXTERNAL NAME [Database1].[StoredProcedures].[SqlStoredProcedure2];
我想一旦我改变尺寸,它就会改变,但这并没有发生

现在,我正在尝试更改缓冲区的大小。

“8000对我来说似乎是一个死赠品。”对此,我深表歉意, 为什么我把8000放在那里,因为生成的查询是这样的

CREATE PROCEDURE [dbo].[SqlStoredProcedure2] @name [nvarchar](4000),
@backup [varbinary](8000)    OUTPUT
AS EXTERNAL NAME [Database1].[StoredProcedures].[SqlStoredProcedure2];
我想一旦我改变尺寸,它就会改变,但这并没有发生


现在我正在尝试更改缓冲区的大小。

好的,我已经解决了大小问题,我需要使用

SqlFacet(MaxSize = -1)
参数,使sql存储过程看起来像

c#

和生成的查询

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

我仍然有坏运气,在C++中没有输出输出PTR。

< P> OK,我已经解决了大小问题,我需要使用< /P>
SqlFacet(MaxSize = -1)
参数,使sql存储过程看起来像

c#

和生成的查询

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

我在C++中没有输出输出PTR的坏运气。< /P> < P> OK,我解决这个问题,这里是正确的方式。< /P>

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

好的,我来解决这个问题,这里是正确的称呼

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

我对SQLCLR的经验是它是一个PoS。当它可以用SQL编写得更简单,性能也会更好时,为什么要使用它。我对SQLCLR的经验是它是一个PoS。当它可以用SQL编写得更简单,性能也会更好时,为什么要使用它。谢谢回复,现在我得到了大小的例外,bytr缓冲区的默认大小是8000,但数据的大小大约是15000,我怎么能增加缓冲区的大小?嗯?代码中有以下行:
unsigned char ptr[8000]=“”;cbParm2=8000
对我来说,
8000
似乎是一个致命的赠品。谢谢你的回复,好吧,现在我得到了大小的例外,bytr缓冲区的默认大小是8000,但数据大小大约是15000,我怎么能增加缓冲区的大小?嗯?代码中有以下行:
unsigned char ptr[8000]=“”;cbParm2=80008000
似乎是一个致命的赠品。