【问题标题】:SQL - inserting into a table defined by a nvarcharSQL - 插入到由 nvarchar 定义的表中
【发布时间】:2016-01-06 09:10:26
【问题描述】:

我的数据库中有几个格式为 PREFIX_FeatureName 的表。例如:

  • Processed_CallingCountry (featureName nvarchar(max) null, escalatedCount int null, featureValue nvarchar(max) null, RequestNumber int null)

  • Processed_CallingCity (featureName nvarchar(max) null, escalatedCount int null, featureValue nvarchar(max) null, RequestNumber int null)

    [...]

目前,每个表都有一个存储过程,用于计算特征并将其插入到正确的表中。每个功能的处理代码几乎相同,功能名称不同。

例子:

SELECT
    (SELECT SUM(IsSpecial) 
     FROM [dbo].[FeaturesBase] 
     WHERE CreatedTime < a.CreatedTime 
       AND CallingCountry = a.CallingCountry ) AS EscalatedCount,
    'CallingCountry' AS FeatureName,
    RequestNumber,
    CallingCountry AS FeatureValue
FROM 
    [dbo].[CssFeaturesBase] a

此代码为所有功能复制粘贴,仅更改功能名称 - 在前面的示例中,“CallingCountry”将替换为其他字符串,每个存储过程一个。

有没有一种方法可以创建一个将字符串作为输入的存储过程,并使用字符串/nvarchar 作为参数进行计算?

基本上,我该怎么做:

CREATE PROCEDURE process (@featureName nvarchar(max))
AS 
BEGIN
    SELECT INTO ('Processed' + @featureName)  -- use the table defined by the string
        (SELECT SUM(IsSpecial) 
         FROM [dbo].[FeaturesBase] 
         WHERE CaseCreatedTime < a.CaseCreatedTime 
           AND @featureName = a.@featureName) AS EscalatedCount,  --use @featureName as column name
        @featureName AS FeatureName,   --use the string literal here
        RequestNumber,
        @featureName AS FeatureValue  --select the proper value
    FROM
        [dbo].[FeaturesBase] a

【问题讨论】:

  • 您需要动态 SQL。这是一个例子:stackoverflow.com/a/11108520/3854195
  • 表中所有行的 FeatureName 是否相同?表名的 FeatureName 部分与插入到表中的 FeatureName 字段中的值相同吗?

标签: sql sql-server stored-procedures


【解决方案1】:

您可能可以使用动态 sql 来解决这个问题:

类似

CREATE PROCEDURE process (@featureName nvarchar(max))
AS 
BEGIN

    declare @sql nvarchar(max);

    SET @sql = 'SELECT INTO (Processed_'+ @featureName + ') 
        (SELECT SUM(IsSpecial) FROM [dbo].[FeaturesBase] where CaseCreatedTime < a.CaseCreatedTime AND ' + @featureName +' =  a.'+ @featureName+ ')  as EscalatedCount,  
        '''+@featureName+''' AS FeatureName,
        RequestNumber,
        ' + @featureName + ' AS FeatureValue 
    from [dbo].[FeaturesBase] a'

    exec(@sql);
End

我已经对此进行了测试,它应该执行以下操作

SELECT INTO (Processed_CallingCountry) 
        (SELECT SUM(IsSpecial) FROM [dbo].[FeaturesBase] where CaseCreatedTime < a.CaseCreatedTime AND CallingCountry =  a.CallingCountry)  as EscalatedCount,  
        'CallingCountry' AS FeatureName,
        RequestNumber,
        CallingCountry AS FeatureValue 
    from [dbo].[FeaturesBase] a

你应该可以在这里找到更多https://msdn.microsoft.com/en-GB/library/ms188001.aspx

【讨论】:

  • 9 个月没有写作,在我完成答案之前就打败了我。欢迎回来。
  • 这看起来可行;有没有办法验证动态 SQL 的语法?
  • 要验证,您可以简单地通过打印 sql 变量 print (@sql); 来验证在这种情况下。如果您需要更健壮的方法,这可能有用social.technet.microsoft.com/wiki/contents/articles/…
【解决方案2】:

在详细了解如何插入数据之前,这里需要解决几个问题:

  1. 为什么featureNameNVARCHAR(MAX)?它会有超过 4000 个字符吗?我怀疑它应该更接近NVARCHAR(20)
  2. 为什么featureName 允许NULLs?不应该是NOT NULL吗?
  3. 很可能featureName 字段甚至不应该出现在这些表中。您需要一个名为Feature 的查找表,其中包含FeatureID INT NOT NULL PRIMARY KEYFeatureName NVARCHAR(20) NOT NULL。然后,这些其他表只有 FeatureID INT 字段和定义的引用 Feature(FeatureID) 的外键。
  4. 您很可能不需要针对不同功能使用单独的表格?它们具有完全相同的结构,并且您已经有一个字段(即 featureName)来区分行。为什么不只拥有一个包含以下字段的 Processed 表:(FeatureID INT NOT NULL, escalatedCount int null, featureValue nvarchar(max) null, RequestNumber int null)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 2018-02-25
    相关资源
    最近更新 更多