【问题标题】:SQL Server concatenate procedureSQL Server 连接过程
【发布时间】:2016-06-23 14:52:33
【问题描述】:

我正在尝试学习如何使用串联过程,但它没有返回我想要的结果。即使我使用命令

EXEC SP_NAME_PROCEDURE NULL,NULL,NULL,NULL 

或使用正确的数据。

ALTER PROCEDURE SP_LISTA_PEDIDOS
    @Sdatainicio varchar(100),
    @Sdatafim varchar(100),
    @chaveBusca varchar(100),
    @TipoBusca varchar(100)
AS 
    DECLARE @SQL VARCHAR(8000)

    SET @SQL += 'SELECT *,b.descricao as dscstatus,c.nome as cliente '

    SET @SQL += ' FROM pedidos   a with(nolock), '
    SET @SQL += ' pedidos_status b with(nolock), '
    SET @SQL += ' cadastro c with(nolock) '

    SET @SQL += ' WHERE '
    SET @SQL += ' a.status <> '''' and '
    SET @SQL += ' a.status=b.status and '
    SET @SQL += ' a.id_doc = c.id_doc '

    IF isnull(@chaveBusca,'')<>''
    BEGIN
        IF isnull(@TipoBusca,'') = 'PEDIDO'
           SET @SQL += ' and a.numped= '''+@chaveBusca+''''

        IF isnull(@TipoBusca,'') = 'CLIENTE'
           SET @SQL += ' and c.nome like '''+@chaveBusca+'%'''
    END

    IF not (isnull(@chavebusca,'')<>'' and isnull(@TipoBusca,'') = 'PEDIDO')
        SET @SQL += ' and data_inclusao BETWEEN '''+@Sdatainicio+''' AND '''+@Sdatafim+''''

    SELECT @SQL

你们能帮我找出问题所在吗?

【问题讨论】:

  • “但它没有给我想要的结果。” - 好吧,它给了你什么结果,它想要什么?注意:这里是 sql 注入的噩梦。您实际上可以使用带有sp_executesql 的可变参数。 @SQL 的最终值将有助于我们调试
  • 你还没有处理前两个参数的NULL。
  • 旁注:您应该为您的存储过程使用sp_ 前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免 sp_ 并使用其他东西作为前缀 - 或者根本不使用前缀!
  • 设置Bad Habits to kick - putting NOLOCK everywhere - 不建议在任何地方使用它 - 恰恰相反!
  • 感谢您的提示。我是新手,真的很想了解更多。我会留意程序名称。关于结果,当我使用 NULL 作为值时,我希望它给我完整的表(没有 WHERE 子句)。

标签: sql-server stored-procedures concatenation


【解决方案1】:

在连接字符串时,您必须检查 NULL 的值,因为 NULL + stringNULL

例如,检查您的第一行:

应该是:

DECLARE @SQL VARCHAR(8000) = ''

此外,您应该添加对输入参数的检查。例如:

ISNULL(@chaveBusca, '')

【讨论】:

  • 我没有处理的唯一参数是日期。初始日期和最终日期。不过谢谢,对我帮助很大
  • 我理解你设置@SQL varchar(100)=''的原因,但它仍然给了我空表
  • 在你的问题中 - 显示你是如何执行程序的
【解决方案2】:

将初始值赋给@SQL VARCHAR(8000)='',因为NULL+Value结果为NULL。

并且您可以将默认值设置为 NULL 或 ''(空格)并在没有输入值的情况下执行,而不是使用 NULL 作为输入值执行。

    EXEC SP_LISTA_PEDIDOS

试试这个脚本。

    ALTER PROCEDURE SP_LISTA_PEDIDOS
    -- EXEC SP_LISTA_PEDIDOS @Sdatainicio='Test1',@Sdatafim='Test2',@chaveBusca='Test3',@TipoBusca='Test4'
    @Sdatainicio varchar(100) ='',
    @Sdatafim varchar(100) ='',
    @chaveBusca varchar(100) ='',
    @TipoBusca varchar(100) =''

    AS 
    DECLARE @SQL VARCHAR(8000)=''

    SET @SQL += 'SELECT *,b.descricao as dscstatus,c.nome as cliente '

    SET @SQL += ' FROM pedidos   a with(nolock), '
    SET @SQL += ' pedidos_status b with(nolock), '
    SET @SQL += ' cadastro c with(nolock) '

    SET @SQL += ' WHERE '
    SET @SQL += ' a.status <> '''' and '
    SET @SQL += ' a.status=b.status and '
    SET @SQL += ' a.id_doc = c.id_doc '


    IF isnull(@chaveBusca,'')<>''
     BEGIN

      IF isnull(@TipoBusca,'') = 'PEDIDO'
         SET @SQL += ' and a.numped= '''+@chaveBusca+''''

      IF isnull(@TipoBusca,'') = 'CLIENTE'
         SET @SQL += ' and c.nome like '''+@chaveBusca+'%'''
     END

    IF not (isnull(@chavebusca,'')<>'' and isnull(@TipoBusca,'') = 'PEDIDO')
        SET @SQL += ' and data_inclusao BETWEEN '''+@Sdatainicio+''' AND '''+@Sdatafim+''''

    SELECT @SQL

【讨论】:

  • 它仍然给了我空表
  • 我得到带参数和不带参数的结果...你修改了脚本吗?
  • yes.. 还为前两个参数添加了空检查
  • 只需在我的帖子中执行脚本并与我分享更新。
  • 它给了我一个 1x1 的表,并以此为值: SELECT *,b.descricao as dscstatus,c.nome as cliente FROM pedidos a with(nolock), pedidos_status b with(nolock), cadastro c with(nolock) WHERE a.status '' and a.status=b.status and a.id_doc = c.id_doc and data_inclusao BETWEEN 'Test1' AND 'Test2'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多