我试图从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
中没有任何内容?这有什么不对?
答案 0 :(得分:3)
我建议您在集成之前对C#代码进行单元测试。你的C#代码有很多问题。第一个是你没有在C#代码中传递参数。
在执行阅读器之前添加以下内容。
cmd.Parameters.AddWithValue( "@name", name );
此外,你的while循环没有任何意义(你忽略了所有的图片,但是最后一张)你应该使用using
作为cmd。
正如旁注所知 - 在开始和结束时使用通配符这样的搜索会非常慢。
SQL Server具有全文搜索功能,可作为单独的功能使用。
答案 1 :(得分: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;
}
}
答案 2 :(得分:0)
“8000对我来说似乎是一个死的赠品。”对不起, 为什么我把8000放在那里因为这是生成查询的样子,
CREATE PROCEDURE [dbo].[SqlStoredProcedure2] @name [nvarchar](4000),
@backup [varbinary](8000) OUTPUT
AS EXTERNAL NAME [Database1].[StoredProcedures].[SqlStoredProcedure2];
我认为一旦改变尺寸就会发生变化,但这并没有发生。
现在我正在尝试更改缓冲区的大小。
答案 3 :(得分: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中没有。