SQL Server如何提及动态列值不应为null

SQL Server如何提及动态列值不应为null,sql,sql-server,tsql,dynamic-sql,Sql,Sql Server,Tsql,Dynamic Sql,首先看几个屏幕截图。 请参见第二个屏幕截图。其中,2010 FYA和其他列为动态列。请参阅动态列值为NULL的第一条记录。现在请告诉我,在获取数据时,动态列值不应为null 这是代码 通过这种方式,我将动态列方式的vaue存储到#TmpZacksCons临时表中 SET @sql='Insert Into #TmpZacksCons (Section, LineItem,Ord, '+@PeriodCols+' ) Select b.Section,

首先看几个屏幕截图。

请参见第二个屏幕截图。其中,2010 FYA和其他列为动态列。请参阅动态列值为NULL的第一条记录。现在请告诉我,在获取数据时,动态列值不应为null

这是代码 通过这种方式,我将动态列方式的vaue存储到#TmpZacksCons临时表中

 SET @sql='Insert Into #TmpZacksCons (Section, LineItem,Ord,      
 '+@PeriodCols+'      
 )      
 Select b.Section, b.LineItem,Max(Ord)+1 Ord,      
 '+@AvgSql+'      
  From #TmpAll_Broker_LI b       
  Group By b.Section, b.LineItem'      
 EXEC(@sql)  
这是我的最后一个查询,返回需要过滤掉空值的全部数据。空数据不应该出现

 SET @sql = '      
 Select XX.*,'''' scale,Isnull(AllowComma,''FALSE'') AllowComma,Isnull(AllowedDecimalPlace,''0'') AllowedDecimalPlace,      
     Isnull(AllowPercentageSign,''FALSE'') AllowPercentageSign,Isnull(CurrencySign,'''') CurrencySign,Isnull(BM_Denominator,'''') BM_Denominator      
 From       
 (      
 ---- Broker Detail      
 Select AA.Section,AA.LineItem,Csm.DisplayInCSM ,AA.BrokerCode Broker,AA.BrokerName,'''' BM_Element,'''' BM_Code,AA.Ord,AA.[Revise Date],AA.LineItemId,      
   Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],      
 '+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment      
 From tblCSM_ModelDetails Csm LEFT OUTER JOIN  (      
Select b.*,L.ID LineItemId         
  From #TmpAll_Broker_LI b      
  INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem      
     ) AA ON Csm.LineItemId=AA.LineItemId      
 WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+' AND Csm.BMID=0 AND Type !=''SHEET''      
 UNION       
 ----- Consensus      
 Select Section, b.LineItem,DisplayInCSM, '''' Broker,'''' BrokerName,'''' BM_Element,'''' BM_Code, Ord,'''' [Revise Date],L.ID LineItemID,      
   Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],      
  '+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment      
  From #TmpZacksCons b      
  INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem      
  INNER JOIN tblCSM_ModelDetails Csm ON Csm.LineItemID=L.ID      
  WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+' AND Csm.BMID=0      
 ---- Blue Metrics      
     UNION      
  Select Section, b.LineItem,DisplayInCSM,'''' Broker,'''' BrokerName,BM_Element,Code BM_Code, Ord,'''' [Revise Date],L.ID LineItemID,      
   Csm.ID,[FontName],[FontStyle],[FontSize],[UnderLine],[BGColor],[FGColor],[Indent],[Box],[HeadingSubHeading],      
   '+@PeriodCols+','+@PeriodColsComment +',LineItem_Comment,BrokerName_Comment,Date_Comment      
  From #TmpBM b      
  INNER JOIN TblLineItemTemplate L ON TickerID='''+@TickerID+''' AND b.LineItem= L.LineItem      
  INNER JOIN tblCSM_ModelDetails Csm ON Csm.BMID=b.code AND Csm.LineItemID=L.ID      
  WHERE Csm.CSM_ID='+TRIM(CONVERT(CHAR(10),@CSM_Id))+'      
  AND Ord IS NOT NULL      
 ) XX       
 Left Outer Join tblLiConfig ZZ      
  On XX.Section=ZZ.Section And XX.LineItem=ZZ.LI And ZZ.Ticker='''+@Ticker+'''      
 Order by ID,Ord,BM_Code,LineItem,BrokerName'  

好的。。。对不起,这是个糟糕的回答。一个非常糟糕的答案。这是当你现在需要解决问题,却没有时间正确解决问题时的答案

真正的解决方法是在将没有有效值的行组合到用于创建表的数据集中之前排除这些行。但是,如果不更深入地了解您的流程/数据,我无法做到这一点。相反,我有一份完整的工作

不管怎样,从我所能告诉你的

  • 在表中#TmpZacksCons
  • 在某些行中,与日期相关的所有列都为空
  • 你想排除这些吗
  • 列名是动态设置的-它们位于变量@PeriodCols中
您可以做的是删除#TmpZacksCons中所有为空的行。当然,问题是这些列是动态创建的

因此,在您现有的命令之后

 SET @sql='Insert Into #TmpZacksCons (Section, LineItem,Ord,      
 '+@PeriodCols+'      
 )      
 Select b.Section, b.LineItem,Max(Ord)+1 Ord,      
 '+@AvgSql+'      
  From #TmpAll_Broker_LI b       
  Group By b.Section, b.LineItem'      
 EXEC(@sql) 
我建议使用DELETE命令删除所有列都为NULL的列

更新

(这个新版本基于更新的知识-我不认为COALESCE可以返回NULL)

这里的hackjob是基于我们不知道列名的事实,所以我们不能只测试列1是否为null,列2是否为null,等等。 所以我要做的是使用一个表达式来查找所有列是否都为NULL,因为它将返回列表中的第一个非NULL值

SET @sql='DELETE FROM #TmpZacksCons 
          WHERE COALESCE('+@PeriodCols+',NULL) IS NULL'
EXEC (@sql)
如果COALESCE表达式返回NULL,则表示所有列都有NULL值

注意,如果列列表只有一列,则合并中还有一个空值

以前的版本-不再相关

所以我要做的是创建一个“幻数”,它表示所有列都是空的,通过在列表中找到第一个非空值的表达式

SET @sql='DELETE FROM #TmpZacksCons 
          WHERE COALESCE('+@PeriodCols+',NULL) IS NULL'
EXEC (@sql)
所以,在你发出上述命令后,我建议


如果所有值都为空,则合并将返回-99999.9999,然后触发删除


当然,上面的问题是,如果任何实际值等于神奇数字-99999.9999,它可能会删除该行。

您的问题是什么?别忘了,我们无法运行您的代码,当然您不应该期望我们转录该图像中的所有数据。花点时间给我们一个答案(我怀疑我们需要所有这些数据)。另外,不要将参数注入到动态语句中。建议阅读:。当列为null时,COALESCE将返回-99999.9999?假设列不是空的,而列的值是空的……那么我该如何管理呢?谢谢你的回答。对不起,我应用了你的代码,但它不起作用。这里是url,您可以从中看到完整的SP代码,并告诉我如何过滤空值。很抱歉-我无法理解您的代码,可能需要几个小时(即使有完整的数据等)才能弄清楚它在做什么。如果它不能满足您的需要,您可能希望将其作为“已接受答案”删除。然而,我认为如果这不起作用,你需要澄清什么是真正需要的。重新合并-其工作方式是查找列表中的第一个非空值。如果您有动态列,那么很难显式地编写检查代码-我使用的是COALESCE可以获取逗号分隔的列列表这一事实。但是,它不适用于空白。注意,我在联合表达式中将此答案更新为更可靠的答案/方法。它可以修复由于计算工作不正常而出现的错误(例如,如果它没有返回相同的数据类型)。然而,它无法解决“空白怎么办”的问题。
SET @sql='DELETE FROM #TmpZacksCons 
          WHERE COALESCE('+@PeriodCols+',-99999.9999) = -99999.9999'
EXEC (@sql)