动态查询过程

时间:2019-02-22 21:56:42

标签: sql sql-server dynamic procedure

我有类似的问题:Stored Procedure with Dynamic Query,但我不能这样做。我有100个类似的表,我想创建动态过程,但是它不起作用。

create or alter procedure Tab  
(
    @z nvarchar(50) = ISNULL,
    @s varchar(30) = ISNULL,
    @l nvarchar(30) = ISNULL)
as 
begin
    Declare @SQLQuery NVARCHAR(50)

    exec ('select * from'  + @l)  as p 
           join z as z on p.C = z.C 
           where @z in (home, away)
             and p.s = @s 
             and z = @z
 end

好,所以我在mssql服务器中有100个表国家c,并且我不想互相写100个存储过程,而是为所有这些写一个。

这是一张桌子的程序代码

create or alter procedure Tabela  
    (@zwyc  nvarchar(50) = ISNULL ,
     @season nvarchar(50) = ISNULL ,
     @lig nvarchar(50) = ISNULL)
as 
begin
    Declare @SQL NVARCHAR(max)
    set @SQL = 'select * from '+@lig+' as p 
    join zwyc z on p.Country=z.Country 
    where '+@zwyc+' in  (home, away) 
    and p.season = '+@season+' and z.zwyc = '+@zwyc
    exec (@sql)
go

现在我想在存储过程中创建一个动态查询以连接到所有国家POR,GER,SWE,ENG ...

样本视图表POL(@lig)

IDPOL   Country League  Season  data    Time    Home    Away    
1   Poland  Ekstraklasa 2012/2013   2012-08-17  17:00:00.0000000    Pogon Szczecin  Zaglebie    
2   Poland  Ekstraklasa 2012/2013   2012-08-17  19:30:00.0000000    Piast Gliwice   Gornik Z.   
3   Poland  Ekstraklasa 2012/2013   2012-08-18  12:30:00.0000000    Jagiellonia Podbeskidzie    
4   Poland  Ekstraklasa 2012/2013   2012-08-18  14:45:00.0000000    Widzew Lodz Slask Wroclaw   
5   Poland  Ekstraklasa 2012/2013   2012-08-18  17:00:00.0000000    Lech Poznan Ruch    
6   Poland  Ekstraklasa 2012/2013   2012-08-19  13:30:00.0000000    Wisla   GKS Belchatow   
7   Poland  Ekstraklasa 2012/2013   2012-08-19  16:00:00.0000000    Legia   Korona Kielce   
8   Poland  Ekstraklasa 2012/2013   2012-08-20  17:30:00.0000000    Lechia Gdansk   Polonia Warszawa    
9   Poland  Ekstraklasa 2012/2013   2012-08-24  17:00:00.0000000    Zaglebie    Piast Gliwice   
10  Poland  Ekstraklasa 2012/2013   2012-08-24  19:30:00.0000000    Jagiellonia Gornik Z.   

SQL Server返回此错误:

  

信息102,级别15,状态1,过程Tabela,第12行[批处理开始第1行]
  ')'附近的语法不正确

我更改表名

这是一个国家的联合查询

select top 10 
    IDPOL, p.country, p.league, p.Season, data, time ,home, away 
from 
    POL p
join 
    zwyciezcy z on p.Country = z.Country 
where 
    p.Season = '2012/2013'
    and z.Zwyciezca = 'Slask Wroclaw'
    and (home = 'Slask Wroclaw' or away = 'Slask Wroclaw')

这是结果

IDPOL   country league  Season  data    time    home    away    
-----------------------------------------------------------------------
4   Poland  Ekstraklasa 2012/2013   2012-08-18  14:45:00.0000000    Widzew Lodz Slask Wroclaw   
14  Poland  Ekstraklasa 2012/2013   2012-08-26  13:30:00.0000000    Slask Wroclaw   Korona Kielce   
23  Poland  Ekstraklasa 2012/2013   2012-09-02  16:00:00.0000000    Slask Wroclaw   Ruch    
25  Poland  Ekstraklasa 2012/2013   2012-09-14  17:00:00.0000000    Podbeskidzie    Slask Wroclaw   
38  Poland  Ekstraklasa 2012/2013   2012-09-23  13:30:00.0000000    Slask Wroclaw   GKS Belchatow   
46  Poland  Ekstraklasa 2012/2013   2012-09-30  13:30:00.0000000    Gornik Z.   Slask Wroclaw   
55  Poland  Ekstraklasa 2012/2013   2012-10-07  16:00:00.0000000    Slask Wroclaw   Polonia Warszawa    
62  Poland  Ekstraklasa 2012/2013   2012-10-21  13:30:00.0000000    Lechia Gdansk   Slask Wroclaw   
70  Poland  Ekstraklasa 2012/2013   2012-10-28  13:30:00.0000000    Slask Wroclaw   Zaglebie    
80  Poland  Ekstraklasa 2012/2013   2012-11-05  17:30:00.0000000    Pogon Szczecin  Slask Wroclaw   

2 个答案:

答案 0 :(得分:0)

这是SQL Server,MySQL或Oracle,MS Access还是....什么?请更改与问题关联的标签。答案将需要相应地更改。

请先编辑第一个问题,然后再添加>>>>分隔符,然后粘贴更正或修订,并保持上面的所有内容,而不是开始新的答案。

然后,请注意

Declare @SQL NVARCHAR(50)  

需要为(500)(或更多),因为我们想出的可能是冗长的SQL。

我从第二个SQL得到的是

select * 
from LLL as p 
join z as z on p.C = z.C 
wher

在50个字符后被截断了。

此外,它可以连续几行,因此为了便于阅读,请对其进行换行。没有参数会是什么样?

另外,参数也不应该是单个字母(@ z,@ s,@ l以及s,z,p,...),而应该是描述性的。

最后,我们需要从输出的外观开始。

SQL过程似乎只有一个带有联接的选择。这是要运行100次吗? 100个结果?

还是我们要将100个表联接成一个结果?

最后,让我们看一些输入。因此,请通过运行并粘贴第1行5或10行来向我们显示这些表名

USE StackOver-or-your-db-name; 

SELECT name, max_column_id_used 
FROM sys.Tables  (maybe, WHERE name like 'xxx*')

以及一个输入DDL的结构。

表中数据的前几行,例如POR

当您说它不起作用时,请告诉我们SQL中的行和收到的消息。

---------- 2月24日上午1点

进展顺利。不创建proc 1st,而是使sql正常工作。
请将arg @zwyc更改为与表名称不同的名称,以免造成混淆;也许@cname。

请打印要连接的表zwyc的几行。 这是我正在测试的东西。我添加了许多双引号来包围varchar args。在EXEC之前,我添加了

 Print @sql

查看将执行的SQL。然后将我的sql arg值更改为适合您的值, 并粘贴回您上方的区域,这样我就知道您尝试了什么...注意到任何其他问题...

 Declare
         @zwyc  nvarchar(50) = 'Poland' ,
         @season nvarchar(50) = '2012/2013' ,
         @ateam nvarchar(50) = 'Wisla',
         @lig nvarchar(50) = '[StackOver].[dbo].[DynamicQueryPOL]'

        Declare @SQL NVARCHAR(max)
        set @SQL = 'select * from ' + @lig + ' as p 
        join zwyc z on p.Country=z.Country 
        where ( p.home =  ''' + @ateam + '''   OR  p.away  = ''' + @ateam + ''' ) 
        and p.season = ''' + @season + ''' and z.zwyc = ''' + @zwyc + ''''
        print @sql
        --exec (@sql)

---------- 2月24日太平洋标准时间(PDT)

结果好吗?修改后的参数对周围的单引号似乎有效。

是否始终提供所有3个参数?还是其中一些为空/不提供?

我注意到 列表中的国家/地区始终是“波兰”

我们为什么要加入?我们只有一排回来吗?好像我们得到12行左右...

join zwyciezcy z  on p.Country=z.Country 

然后按团队名称将这12行过滤为仅一行。

where ::: z.Zwyciezca='Slask Wroclaw'

但是我们没有使用表zwyciezcy z中的其他列。那么为什么要执行联接?

请打印要连接的表zwyciezcy的几行。

答案 1 :(得分:0)

查询中的问题: 在动态查询中,您没有正确处理z.Zwyciezca = 'Slask Wroclaw'。您的处理方式是:z.Zwyciezca = Slask Wroclaw不包含'

select *
from 
    POL p
join 
    zwyciezcy z on p.Country = z.Country 
where 
    p.Season = '2012/2013'
    and z.Zwyciezca = 'Slask Wroclaw'
    and (home = 'Slask Wroclaw' or away = 'Slask Wroclaw')

上面的示例动态查询应类似于:

Declare @SQL NVARCHAR(max)
    set @SQL = 'select * from '+@lig+' as p 
    join SomeTable z on p.columnname= z.columnname
    where p.columnName in  (''home'', ''away'') 
    and p.anothercolumn= '''+@season + ''''

    print @SQL
    exec (@sql)