【问题标题】:Temp table has only one row inserted临时表只插入了一行
【发布时间】:2016-07-01 03:33:03
【问题描述】:

您好,我有一个 SP,我在其中创建了一个临时表来存储一些值。

ALTER PROCEDURE [dbo].[test] 
  @id int,
  @funds_limit money
AS
BEGIN
      SET NOCOUNT ON;
      DECLARE @threshold money;

      CREATE TABLE #ConfigurationTemp 
                    (id int, 
                     name varchar(100) not null,
                     type varchar(100),
                     value varchar(100))

      INSERT #ConfigurationTemp EXEC get_config @id, 'testType', null

      select @threshold = value 
      from #ConfigurationTemp 
      where id=@id and name='testLimit'
      print @threshold

      IF (@funds_limit IS NOT NULL) AND (@threshold < @funds_limit)
      BEGIN
         DROP TABLE #ConfigurationTemp;
         RETURN 1000;
      END

      select @threshold = value 
      from #ConfigurationTemp 
      where id=@id and name='testLimit1'
      print @threshold

      IF (@funds_limit IS NOT NULL) AND (@threshold < @funds_limit)
      BEGIN
           DROP TABLE #ConfigurationTemp;
           RETURN 1001;
      END    
    END        
    RETURN 0;
END

临时表有多行。 例如:

1, fund_limit, testType, 10
2, fund_min_limit, testType, 20

我需要首先使用用户输入值(将成为 SP 的输入参数)验证 fund_limit (10) 的值。如果验证失败,我会返回错误代码。如果没有,我去下一次检查。即,fund_min_limit。我对它做同样的事情并返回一个不同的错误代码。如果没有验证失败,我将返回 0,这被认为是成功的。

在这种情况下,我总是得到相同的阈值。即第一行的值... 10.

如何从临时表中获取与名称相关的不同阈值?

【问题讨论】:

  • 旁注:临时表在退出创建它们的存储过程时会自动删除。无需手动DROP TABLE
  • 另外,你怎么知道它只包含一行?它可以轻松地包含多行,但您的SELECT @scalarvariable = columnvalue 语句显然只会为变量分配一行中的一个可能值。
  • 我只能猜测,但我会说您传递给您的get_config 存储过程的@id 参数可能是问题...?
  • 嗨 Damien,我尝试将阈值分配给不同的值。但是第二个阈值1 没有任何价值。所以我假设临时表中只有一行。
  • 您正在处理此表,因为只有一行。你试过select * from #ConfigurationTemp吗?它会返回一行吗?

标签: sql sql-server sql-server-2008 temp-tables


【解决方案1】:

您的IF 声明中有RETURN

  ... RETURN 1000
  and 
  ... RETURN 1001

插入一行后程序结束。

也许您想将结果分配给变量

@return_Value = ''

    @return_Value = @return_Value + '1000, '             
 ....
    @return_Value = @return_Value + '1001, '

RETURN @return_Value

【讨论】:

  • 如果出现一个错误,我需要从 SP 中退出。这就是我从 if 条件返回的原因。
【解决方案2】:

当您使用select 分配标量变量时 - 如果此选择返回零行,则可能未分配(未更改 - 可能保留先前分配的值)。为确保您的变量更改了它的值,请将其重写为 set 表达式。

因此,如果您拼错了第二个阈值名称,您可能会“获取”相同的@threshold 值,因为第二个语句没有为您的变量分配任何内容,即变量包含先前分配的值(选择)。您可以使用第二个阈值的附加变量对其进行测试 - 如果我猜到问题原因,它将始终为 NULL。

您还应用了相同的@id 过滤器,它是一个标量变量。但是你的行有不同的 id。因此,除了给定的@id 之外,现在没有机会获得任何其他阈值。

  set @threshold = (select t.value 
    from #ConfigurationTemp t
    where t.name='testLimit')
  print @threshold

  IF @threshold < @funds_limit
     RETURN 1000;

  set @threshold = (select t.value 
    from #ConfigurationTemp t
    where t.name='testLimit 2')
  print @threshold

  IF @threshold < @funds_limit
       RETURN 1001;

If 只有在两个参数都不为空时才会成功。

另一种方法:

declare
  @threshold_a int,
  @threshold_b int,
  @threshold_c int

;with test as
(
  select 'a' as name, 25 as value
  union all
  select 'b', 3
  union all
  select 'c', 100
  union all
  select 'd', -1
)
select
  @threshold_a = case when t.name = 'a' then t.value else @threshold_a end,
  @threshold_b = case when t.name = 'b' then t.value else @threshold_b end,
  @threshold_c = case when t.name = 'c' then t.value else @threshold_c end
from test t

select
  @threshold_a as [a],
  @threshold_b as [b],
  @threshold_c as [c]

GO

单选,多个变量。

【讨论】:

  • 我也有同样的问题。在我的情况下,临时表中有 4 行具有相同的 ID 和类型。但名称不同。我想获得这 4 个不同名称的阈值。所以每次我写一个 Sreeshad 提到的选择查询。我第一次得到价值。但是在第二次将值分配给新变量时,我得到空值。似乎我的临时表没有与我第二次提到的名称相对应的行。我在做什么有问题吗?
  • @DivyaRose 您是否尝试在没有过滤器的情况下使用select * 来检查您的临时表中有什么?
  • 是的。我做到了。有4行。在那之前,一切似乎都很好。验证开始时,表格中似乎只有一行。
  • 我添加了另一种方法 - 您可以尝试一下。在代码中,您检查了where 过滤器 - 可能是您遗漏了一些东西。或者像 Sreeshad 尝试使用相同的 @id 值进行过滤,而实际上每一行中都有不同的 id。
  • 我认为第二种方法可能对我有用。
猜你喜欢
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 2012-08-19
  • 2018-11-20
  • 2011-11-14
相关资源
最近更新 更多