从SQL Server 2008存储过程通过ODBC输出到C#

时间:2012-02-24 15:58:47

标签: c# sql-server-2008 stored-procedures odbc

我正在尝试使用ODBC连接通过C#程序连接到SQL Server 2008数据库。我正在发送一个存储过程的一些数据,以便更新一些记录。我想找回某种输出消息以确保我的Proc正在运行。在我开始搞乱输出消息之前,我的proc运行,根据我的C#程序,它从未返回错误。但是数据库没有更新。一旦我添加了允许输出的代码,我就得到了一个错误,就像HY105一样。代码如下:

PROC -

ALTER PROCEDURE [dbo].[Proc]
(   @userid                                 char(10),
@sql_userid                         varchar(50),
@user_encrypted_password        varchar(50),
@user_old_sql_guid_password     varchar(50),
@user_new_sql_guid_password     varchar(50),
    @user_new_sql_guid_encrypted_password   varchar(50),
    @errmsg                 int OUTPUT

)

as

DECLARE @now            datetime,
    @status         int,
    @InProcErrMsg   varchar(255)

SET @userid = UPPER(@userid)

BEGIN TRY  

EXEC ("ALTER LOGIN" + @sql_userid + "WITH PASSWORD  = " +
    @user_new_sql_guid_password + 
            " old_password = " + @user_old_sql_guid_password);

SET @errmsg = 0

IF @@ERROR = 0
    BEGIN
    UPDATE  Table
    Set     SERVER_OTHER = @user_new_sql_guid_encrypted_password
    WHERE   PC_LOGIN = @userid
            and PC_OTHER = @user_encrypted_password

    END 
SET @errmsg = 1
End try

begin catch
if @@trancount > 0
    rollback transaction

select @InProcErrMsg = left( "Proc: (" + cast( error_line() as varchar(10) ) + ") " 
+ error_message(), 255 )
raiserror 50000 @InProcErrMsg

end catch

return 0`

C# -

using (OdbcConnection databaseConnection = new OdbcConnection
                     ("Driver={SQLServer};Server=server;UID=id;PWD=pw;Database=db;"))
   {
     try
        {
         OdbcCommand SQLUserUpdateCommand = new OdbcCommand
           ("{? = CALL USP_PHD_SQLUSER_UPDATE(?,?,?,?,?,?)}", databaseConnection);

         SQLUserUpdateCommand.CommandType = CommandType.StoredProcedure;

         OdbcParameter SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                                             ("@userid", OdbcType.Char, 10);
         SQLUserUpdateParam.Value = id;

         SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                              ("@sql_userid", OdbcType.VarChar, 50);
         SQLUserUpdateParam.Value = sqlid;

         SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                              ("@user_encrypted_password", OdbcType.VarChar, 50);
         SQLUserUpdateParam.Value = pw;

         SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                              ("@user_old_sql_guid_password", OdbcType.VarChar, 50);
         SQLUserUpdateParam.Value = oldpw;

         SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                              ("@user_new_sql_guid_password", OdbcType.VarChar, 50);
         SQLUserUpdateParam.Value = newpw;

         SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                       ("@user_new_sql_guid_encrypted_password", OdbcType.VarChar, 50);
         SQLUserUpdateParam.Value = as_encrypted;

         SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                              ("@errmsg", OdbcType.VarChar, 255);
         SQLUserUpdateParam.Direction = ParameterDirection.Output;

         databaseConnection.Open();

         SQLUserUpdateCommand.ExecuteNonQuery();

         SQLUserUpdateCommand.Dispose();
         databaseConnection.Close();
         }
         catch (OdbcException OEx)
         {
         Trace.WriteLine("Failed to call USP_PHD_SQLUSER_UPDATE");
         Trace.WriteLine("ODBC Exception Message: " + OEx.Message);
         Trace.WriteLine("ODBC Exception Source: " + OEx.Source);
         Trace.WriteLine("ODBC Exception StackTrace: " + OEx.StackTrace);
         Trace.WriteLine("ODBC Exception TargetSite: " + OEx.TargetSite);
         Trace.WriteLine("ODBC Exception Data: " + OEx.Data);
         Trace.WriteLine("ODBC Exception Error Code: " + OEx.ErrorCode);
         Trace.WriteLine("ODBC Exception Errors: " + OEx.Errors);
         }
       }

错误 -

  

发生了'System.Data.Odbc.OdbcException'类型的第一次机会异常   System.Data.dll中
  无法调用Proc
  ODBC异常消息:错误[HY105] [Microsoft] [ODBC SQL Server驱动程序]无效   参数类型
  ODBC异常源:SQLSRV32.DLL
  ODBC异常StackTrace:
  在System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle,RetCode retcode)
  在System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior   行为,   String方法,Boolean needReader,Object [] methodArguments,SQL_API odbcApiMethod)
  在System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior   行为,String方法,Boolean needReader)
  在System.Data.Odbc.OdbcCommand.ExecuteNonQuery()
  at nvo_connect1.of_update(String as_process_name,String as_switch,   String as_server_signon,String as_server,String as_database,   String as_password,String as_decrypted,String as_new_password_guid,   String as_encrypted,String as_400_connection_string)
  ODBC异常TargetSite:Void HandleError(System.Data.Odbc.OdbcHandle,RetCode)
  ODBC异常数据:System.Collections.ListDictionaryInternal
  ODBC异常错误代码:-2146232009
  ODBC异常错误:System.Data.Odbc.OdbcErrorCollection

它没有给我一个行号,但通过测试,我知道错误发生在SQLUserUpdateCommand.ExecuteNonQuery();

如果此网站上有太多信息,就是这样。如果是这样,道歉。第一次使用。

本周我在Google上寻求过多帮助,没有任何结果。我知道它会成为一个前额扒手,但这比现在的桌头砰砰声要好。

感谢您的帮助。

编辑:

@errmsg很重要,谢谢你指出这一点。我改变了我的C#以使其最终工作:

SQLUserUpdateCommand.Connection = databaseConnection;

//*****Open ODBC Connection
databaseConnection.Open();

SQLUserUpdateCommand.CommandType = CommandType.StoredProcedure;

SQLUserUpdateCommand.Parameters.AddWithValue("@userid", as_login_name);
SQLUserUpdateCommand.Parameters.AddWithValue("@sql_userid", as_server_signon);

SQLUserUpdateCommand.Parameters.AddWithValue("@user_encrypted_password", as_password);

SQLUserUpdateCommand.Parameters.AddWithValue("@user_old_sql_guid_password",
                                                                    as_decrypted);

SQLUserUpdateCommand.Parameters.AddWithValue("@user_new_sql_guid_password",
                                                              as_new_password_guid);

SQLUserUpdateCommand.Parameters.AddWithValue("@user_new_sql_guid_encrypted_password",
                                                              as_encrypted);

SQLUserUpdateCommand.ExecuteNonQuery();

我没有使用ODBCParameter对象来添加我的参数,而是使用ODBCCommand对象的AddValue()方法添加了参数。

我一起摆脱了输出参数。决定通过将记录插入表中来检索错误消息。我的alter语句也存在一些问题。总的来说,我不知道问题是什么。我正在使用输出参数的同一个程序中使用另一个proc,所以任何建议都会受到赞赏!

3 个答案:

答案 0 :(得分:1)

这是错误的

SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                              ("@errmsg", OdbcType.VarChar, 255);

因为参数在过程

中以这种方式声明
      @errmsg        int OUTPUT

您应该更新C#代码以匹配例如

SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                              ("@errmsg", OdbcType.Int,);
SQLUserUpdateParam.Direction = ParameterDirection.Output; 

答案 1 :(得分:1)

在您的SP中,它定义:

 @errmsg                 int OUTPUT

但是你在C#中做到了:

SQLUserUpdateParam = SQLUserUpdateCommand.Parameters.Add
                          ("@errmsg", OdbcType.VarChar, 255);

因此它表示无效参数类型

答案 2 :(得分:0)

使用sql profiler工具查看传递给过程的参数。捕获那些并尝试单独执行存储过程,或者可以调试它。你应该能够把错误归零。