ado连接sql server 2000,填加俩个ADOStoredProc控件,ADOStoredProc1在属性里指定存储过程名称,
在Parameters属性里可以看见存储过程的参数。
ADOStoredProc2的存储过程名称以及参数用代码控制。
存储过程有一参数,类型为nVarChar,当该参数传入的值不为空的时候,俩个存储过程都没问题,但是当该参数的值为空字符串的时候,ADOStoredProc1可以正常运行,ADOStoredProc2运行出错,提示大概是这样的:“不能从text到nvarchar的隐性转换,请使用convert运行”,但是如果把该参数改为varchar,不管参数是否为空字符串,俩个存储过程都没问题。在查询分析器里不管参数是否为空字符串,存储过程运行都没问题。超级郁闷,不知道属性里指定储存过程和代码写有什么区别,会造成这样的结果请高手指点一二!!!先谢了

解决方案 »

  1.   

    ADOStoredProc在重新指定存储构过程名称的时候,请用Refresh刷新一下就可以的到SQLServer定义的参数。
      

  2.   

    楼上的好象没明白我的意思,我不是重新指定存储构过程名称,而是想把在属性设置里实现的用代码来实现,因为起初发现问题是由一个DLL引起的。
      

  3.   

    更正一下:“俩个存储过程都没问题”,应该是“俩个ADOStoredProc控件运行都没有问题”
      

  4.   

    存储过程--已经简化了的:
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_gl_detail02]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[sp_gl_detail02]
    GOSET QUOTED_IDENTIFIER ON 
    GO
    SET ANSI_NULLS ON 
    GOCREATE PROCEDURE dbo.sp_gl_detail02
    @digest nvarchar(50)=''  
      
    AS  
      
    set nocount on  
        
    set @digest = '%'+rtrim(@digest)+'%'  select @digestGO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO
      

  5.   

    ADONTemp.Connected := False;
        CommandType := cmdStoredProc;
        Parameters.Clear;
        CommandText := 'dbo.W_RShipM_A';
        Parameters.CreateParameter('RETURN_VALUE', ftInteger, pdReturnValue, 0, NULL);
        Parameters.CreateParameter('@G_StartDate_C', ftString, pdInput, 8, sStartDate);
        Parameters.CreateParameter('@G_EndDate_C', ftString, pdInput, 8, sEndDate);
        Parameters.CreateParameter('@G_UserGuid_C', ftString, pdInput, 38, G_sUserGuid);
        Parameters.CreateParameter('@G_Application_C', ftString, pdInput, 38,G_sApplicationGuid);
        iTimeCount := GetTickCount;
        ADOSReport.Recordset := Execute;
        if Parameters.ParamByName('RETURN_VALUE').Value<>0 then
          raise Exception.Create('&Iacute;&sup3;&frac14;&AElig;&frac14;&AElig;&Euml;&atilde;&sup3;&ouml;&acute;í!');
      

  6.   

    delphi代码(我用的是D7):
    procedure TForm1.Button2Click(Sender: TObject);
    begin
        ADOStoredProc2.ProcedureName := 'sp_gl_detail02';
        ADOStoredProc2.Parameters.AddParameter.Value := '';
        ADOStoredProc2.Active := true;
        showmessage('ok');
    end;错误提示:
    Project Project1.exe raised exception class EOleException with message'不允许从数据类型text到nvarchar的隐性转换。请使用CONVERT函数来运行此查询。'.Process stopped.Use Step or Run to continue.如果把代码换成下面的,正常
    procedure TForm1.Button2Click(Sender: TObject);
    begin
        ADOStoredProc2.ProcedureName := 'sp_gl_detail02';
        ADOStoredProc2.Parameters.AddParameter.Value := '123';//后者别的字符,只要不是空字符串就行
        ADOStoredProc2.Active := true;
        showmessage('ok');
    end;
      

  7.   

    to  CompassButton(北方的郎)
    我写的是一个通用的控件,也就是参数个数和类型都不确定。上边说的只是为了测试写的一个小应用
      

  8.   

    ADOStoredProc2.Parameters.AddParameter.Value := ' ';
    傳個空格就可以啦.
      

  9.   

    to  konhon(优华) :
    可是如果我sp里面没有rtrim,ltrim的话,得到的结果不是歪曲了吗?
      

  10.   

    还有,如果把
    @digest nvarchar(50)='' 
    改成
    @digest varchar(50)='' 
    的话,传空字符串也没有问题不知道啥原理???
      

  11.   

    to  konhon(优华) :
    做了个测试,传空格在delphi下可以,可是我写的控件要asp调用,在asp里传入空格也一样出错。
      

  12.   

    NVarchar要指定相应Parameter的DataType为ftWideString,否则会出错或者处理参数时,不需要一个一个的add,使用Refresh方法后(让控件自动获取参数名和数据类型),直接给参数赋值即可:procedure TForm1.Button2Click(Sender: TObject);
    begin
        ADOStoredProc2.ProcedureName := 'sp_gl_detail02';
        ADOStoredProc2.Parameters.Refresh();
        ADOStoredProc2.Parameters.Parameters.ParamByName('@param_name').Value := '';
        ADOStoredProc2.Active := true;
        showmessage('ok');
    end;
      

  13.   

    //非要自己处理的话,注意添加的Parameter的各个属性最好指定,因为默认的未必是你想要的
      with ADOStoredProc1 do
      begin
        ProcedureName := 'sp_gl_detail02';
        with Parameters.AddParameter do
        begin
          DataType := ftWideString;  //数据类型,NVarchar对应ftWideString
          Name := '@param_name';  //参数名
          Direction := pdInput;   //参数方向,输入还是输出
          Value := '';            //参数赋值
        end;
        Active := true;
      end;
      

  14.   

    刚刚测试了一下,用AddParameter的方式还是会出错,用我前面提供的Refresh之后直接赋值的方式就没问题了。
    可能是我AddParameter的过程还是有些属性值没有指定的缘故,但是明显Refresh是更简单有效并且可以满足楼主要求的做法了
      

  15.   

    不好意思, 上面的AddParameter的方式也没有错, 是我不小心在别的地方搞错了