首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最小化动态sql中的函数调用?

最小化动态sql中的函数调用?
EN

Stack Overflow用户
提问于 2013-07-20 13:41:19
回答 3查看 116关注 0票数 2

如何消除以下动态SQL中的多个转换函数?

代码语言:javascript
复制
IF @MediaTypeID > 0 or @MediaGroupID > 0
BEGIN
    SET @SQL = @SQL + 'INNER JOIN (SELECT lmc.ID FROM Lookup_MediaChannels (nolock) lmc 
                       INNER JOIN Lookup_SonarMediaTypes (nolock) lsmt ON lmc.SonarMediaTypeID = lsmt.ID
                       WHERE (ISNULL('+ CONVERT(VARCHAR(10),@MediaTypeID) +',0) = 0 OR lsmt.ID = '+ CONVERT(VARCHAR(10),@MediaTypeID) +') 
                         AND (ISNULL('+ CONVERT(VARCHAR(10),@MediaGroupID)+',0) = 0 OR lsmt.SonarMediaGroupID = '+ CONVERT(VARCHAR(10),@MediaGroupID) +'))t ON t.ID = lmc.ID '

我尝试先转换它们,然后使用一个变量来代替如下所示的转换调用

代码语言:javascript
复制
IF @MediaTypeID > 0 or @MediaGroupID > 0
       BEGIN
       SET @TypeID = CONVERT(VARCHAR(10),@MediaTypeID)
       SET @GroupID = CONVERT(VARCHAR(10),@MediaGroupID)
          SET @SQL = @SQL + 'INNER JOIN (SELECT lmc.ID FROM Lookup_MediaChannels (nolock) lmc 
                                   INNER JOIN Lookup_SonarMediaTypes (nolock) lsmt ON lmc.SonarMediaTypeID = lsmt.ID
                                   WHERE (ISNULL('+ @TypeID +',0) = 0 OR lsmt.ID = '+ @TypeID +') 
                                   AND (ISNULL('+ @GroupID+',0) = 0 OR lsmt.SonarMediaGroupID = '+ @GroupID +'))'
       END

但它给了我这个错误

Msg 245,第16级,状态1,第13行 当将varchar值',0) =0或lsmt.ID =‘转换为数据类型int时,转换失败。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-20 14:00:01

您所得到的错误是因为您试图将变量MediaTypeID和MediaGroupID从int转换为varchar。那个手术没有失败,只是没有发生。问题是,这两者仍然是整数,您正在尝试添加导致错误的动态代码。所以我所做的就是声明两个新的变量,这应该可以解决问题。如果您查看没有包含的代码,您应该注意到,MediaTypeID和MediaGroupID都是数值型整数。

代码语言:javascript
复制
IF @MediaTypeID > 0 or @MediaGroupID > 0
BEGIN
DECLARE @TypeID2 VARCHAR(10)
DECLARE @GroupID2 VARCHAR(10)

SET @TypeID2 =  NULLIF(CONVERT(VARCHAR(10),@MediaTypeID ), 0)
SET @GroupID2 = NULLIF(CONVERT(VARCHAR(10),@MediaGroupID), 0)
SET @SQL = @SQL + 'INNER JOIN (SELECT lmc.ID FROM Lookup_MediaChannels (nolock) lmc 
                   INNER JOIN Lookup_SonarMediaTypes (nolock) lsmt ON lmc.SonarMediaTypeID = lsmt.ID
  WHERE '+ 
  coalesce( @TypeID2 +' = lsmt.ID', '1=1') +
  coalesce( 'AND' + @GroupID2+' = lsmt.SonarMediaGroupID', '') + ')t ON t.ID = lmc.ID '
END
票数 1
EN

Stack Overflow用户

发布于 2013-07-20 13:51:19

通过将WHERE子句移到代码块开头的变量计算中,您可以重新构造您的ISNULLS子句,以消除查询正文中的ISNULLS。

因此,与其:

代码语言:javascript
复制
SET @TypeID = CONVERT(Varchar(10), @MediaTypeID)

做:

代码语言:javascript
复制
SET @TypeID =  CAST( COALESCE(@MediaTypeID, 0) AS Varchar)

这样,转换就不必发生在查询本身中。

票数 1
EN

Stack Overflow用户

发布于 2013-07-20 20:18:37

您所得到的错误可能是由NULL @MediaTypeID或@MediaGroupID值引起的,因为您的代码没有正确地处理NULL。

但是,具有类似WHERE子句中的OR条件不利于性能,因为它阻止查询优化器使用索引。我建议重写它以避免OR (这也减少了皈依者的数量):

代码语言:javascript
复制
IF @MediaTypeID > 0 or @MediaGroupID > 0
BEGIN
    SET @SQL = @SQL + 'INNER JOIN (SELECT lmc.ID FROM Lookup_MediaChannels (nolock) lmc 
                                INNER JOIN Lookup_SonarMediaTypes (nolock) lsmt ON lmc.SonarMediaTypeID = lsmt.ID 
                                WHERE 1=1 '
    IF @MediaTypeID > 0 
        SET @SQL = @SQL + ' AND lsmt.ID = ' + CONVERT(VARCHAR(10),@MediaTypeID)

    IF  @MediaGroupID > 0
        SET @SQL = @SQL + ' AND lsmt.SonarMediaGroupID = ' + CONVERT(VARCHAR(10),@MediaGroupID)

    SET @SQL = @SQL + ') t ON t.ID = lmc.ID '
END
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17762854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档