【问题标题】:Issues in creating dynamic SQL query创建动态 SQL 查询的问题
【发布时间】:2017-09-12 22:20:33
【问题描述】:

我试图创建一个动态 SQL 查询,但不幸的是它显示了一个错误:

消息 245,第 16 级,状态 1,第 14 行
从 SimulationVisit SV inner join Students on s 转换 varchar 值 'select count (s.ID), count (distinct (s.ID)) 时转换失败。 ID=SV。学生 ID 内部加入 AC 上的 Activity Context AC。 ID=SV。 ActivityContextID WHERE (AC.TenantID = ' 到数据类型 int。

我的代码

declare @DateRangeStart    [DATETIME2](7), 
        @DateRangeEnd      [DATETIME2](7), 
        @TenantID          [SMALLINT] , 
        @ActivityContextID [INT], 
        @StudentID         [INT] = NULL 

'select count(s.ID),count(distinct(s.ID)) 
from SimulationVisit SV  
inner join Student s on s.ID = SV.StudentID  
inner join ActivityContext AC on AC.ID = SV.ActivityContextID 
where (AC.TenantID = ' + @TenantID + ' OR @TenantID is null)
  and (AC.ID =' + @ActivityContextID + ')
  and (SV.StudentID = ' + @StudentID + ')';

请帮我解决这个问题

【问题讨论】:

  • 为什么要为此创建动态 sql 查询。使用普通参数。

标签: sql sql-server sql-server-2008-r2


【解决方案1】:

如果需要动态 sql,则使用参数化动态 sql 查询:

EXEC sp_executesql N'
SELECT COUNT(s.ID),COUNT(distinct(s.ID)) 
FROM SimulationVisit SV  
INNER JOIN Student  S ON s.ID=SV.StudentID  
INNER JOIN ActivityContext AC ON AC.ID=SV.ActivityContextID 
WHERE (AC.TenantID = @TenantID OR @TenantID is null)
AND (AC.ID = @ActivityContextID)
AND (SV.StudentID = @StudentID)',
N'  @TenantID          [SMALLINT] , 
    @ActivityContextID [INT], 
    @StudentID         [INT]',
@TenantID, @ActivityContextID, @StudentID         

【讨论】:

    【解决方案2】:

    由于这是动态sql,所以最终的sql语句需要是varchar。相应地转换输入参数

      'select count(s.ID),count(distinct(s.ID)) from SimulationVisit SV  inner join Student  s on s.ID=SV.StudentID  
                            inner join ActivityContext AC on  AC.ID=SV.ActivityContextID 
                                WHERE (AC.TenantID = '+Cast(@TenantID as varchar(50))+' OR '+Cast(@TenantID as varchar(50))+' is null)
                                 AND (AC.ID =' +Cast(@ActivityContextID as varchar(50))+')
                                 AND (SV.StudentID = '+Cast(@StudentID as varchar(50))+')'
    

    【讨论】:

      【解决方案3】:

      不要创建连接字符串的查询,这是一种不好的做法。只写:

      select count(s.ID),count(distinct(s.ID)) 
       from SimulationVisit SV  
       inner join Student  s 
          on s.ID=SV.StudentID  
       inner join ActivityContext AC 
          on AC.ID=SV.ActivityContextID 
       WHERE (AC.TenantID = @TenantID OR @TenantID is null)
       AND (AC.ID = @ActivityContextID)
       AND (SV.StudentID = @StudentID)
      

      【讨论】:

        【解决方案4】:

        如下更新您的查询,您必须将变量转换为字符串/varchar 值才能执行动态查询

        DECLARE        
            @DateRangeStart    [DATETIME2](7), 
            @DateRangeEnd      [DATETIME2](7), 
            @TenantID          [SMALLINT] , 
            @ActivityContextID [INT], 
            @StudentID         [INT] = NULL 
        
        DECLARE @Query VARCHAR(8000)
        SET @Query='select count(s.ID),count(distinct(s.ID)) from SimulationVisit SV  inner join Student  s on s.ID=SV.StudentID  
                                    inner join ActivityContext AC on AC.ID=SV.ActivityContextID 
                                    WHERE (AC.TenantID = '+CAST(@TenantID AS VARCHAR(10))+' OR @TenantID is null)
                                    AND (AC.ID =' +CAST(@ActivityContextID AS VARCHAR(10))+')
                                    AND (SV.StudentID = '+CAST(@StudentID AS VARCHAR(10))+')'
        
        EXEC(@Query)
        

        【讨论】:

          【解决方案5】:

          将 INT 和 BIGINT 值转换为 VARCHAR 数据类型,格式如下:

             'SELECT count(s.ID),count(distinct(s.ID)) 
              FROM SimulationVisit SV 
              INNER JOIN Student  s on s.ID = SV.StudentID  
              INNER JOIN ActivityContext AC on AC.ID = SV.ActivityContextID 
              WHERE (AC.TenantID = '+ CAST( @TenantID AS VARCHAR ) + ' OR 
                      @TenantID is null) AND 
                    (AC.ID =' + CAST ( @ActivityContextID AS VARCHAR ) + ')
                    AND (SV.StudentID = '+ CAST( @StudentID AS VARCHAR ) +')' 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-08-21
            • 1970-01-01
            • 2013-09-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多