【问题标题】:In Sql Server, how do you put value from cursor into temp table?在 Sql Server 中,如何将游标中的值放入临时表中?
【发布时间】:2014-07-23 15:54:26
【问题描述】:

我正在尝试创建一个包含光标的函数。我想从该游标中获取 Quantity 值并将其放入临时表中。但是我还没有成功获取到值并将其放入临时表中。

我在无法完成的地方发表评论...

这是我的代码

alter FUNCTION test(@input VARCHAR(250)) RETURNS Decimal(8, 2) AS BEGIN

DECLARE @rst Decimal(8, 2) SET @rst=0
DECLARE @Temp TABLE (Quantity Decimal(8,2), Price Decimal(8,2))
DECLARE @amount Decimal(8,2)
DECLARE @price Decimal(8,2)

DECLARE CrsOrfLine CURSOR FOR
SELECT AMOUNT FROM LG_001_01_ORFLINE 
 WHERE LINETYPE    = 0 
 AND ORDFICHEREF = (SELECT TOP 1 LOGICALREF FROM LG_001_01_ORFICHE WHERE GUID='EEB44E72-3717-4F5B-8F7E-6A36EB38EA22')
 ORDER BY LINENO_ ASC;

FETCH NEXT FROM CrsOrfLine INTO  @amount
WHILE (@@FETCH_STATUS = 0) 
BEGIN
     INSERT INTO @Temp (Quantity)

     /* HOW AM I SUPPOSED TO ADD IT INTO THE TEMP?????? */
     /* I COULDNT FIGURE THIS PART OUT                  */

FETCH NEXT FROM CrsOrfLine INTO @amount
END /*WHILE*/
CLOSE CrsOrfLine
DEALLOCATE CrsOrfLine

【问题讨论】:

  • 你会使用INSERT INTO @Temp (Quantity) VALUES (@Amount) - 但是几乎肯定有更好的方法,这个函数的性能会很糟糕!好像an XY Problem。您可能想描述您试图通过您的功能实现的目标并获得答案,而不是如何解决解决方案中的问题。
  • 你到底为什么要使用游标来加载临时表?
  • 你可以SELECT INTO...,它会为你创建表,或者声明它和INSERT INTO...SELECT
  • 虽然我不认为游标在这里是一个合适的解决方案,但你也应该养成为你的需要声明一个合适的游标的习惯,即如果你只是从游标读取使用@987654326 @,如果你只使用过FETCH NEXT,则使用FORWARD_ONLY等。这样可以避免多余的内存使用,并且可以显着提高游标的性能。
  • 顺便说一句,如果您使用 SELECT TOP 1 查询构建游标,您的游标将只运行一次(对于查询返回的一行)然后结束。总是。

标签: sql sql-server temp-tables database-cursor


【解决方案1】:

您可以执行以下操作。请注意,它只插入数量,因此如果您打算包含价格,则需要对其进行修改。

DECLARE @Temp TABLE 
(
  Quantity Decimal(8,2), 
  Price Decimal(8,2)
)


INSERT INTO @temp (Quantity)
SELECT AMOUNT FROM LG_001_01_ORFLINE 
WHERE LINETYPE = 0 
AND ORDFICHEREF = (SELECT TOP 1 LOGICALREF FROM LG_001_01_ORFICHE WHERE GUID='EEB44E72-3717-4F5B-8F7E-6A36EB38EA22 ORDER BY LINENO_ ASC')

【讨论】:

  • 是的,我也需要添加价格,但我不知道如何更新它。有什么想法吗?
  • 您如何获得价格?是否来自同一个SELECT
  • SELECT ORG_PRICE FROM LG_XT002001_001 XT002 WHERE XT002.ORF_GUID='EEB44E72-3717-4F5B-8F7E-6A36EB38EA22' ORFLINE_NO ASC 订单;
  • 如果可能的话,我会重写查询以在一次选择中获取 2 列。然后,您可以从我的查询中删除 (quantity) 或将其更改为 (quantity, price)
【解决方案2】:
CREATE PROCEDURE [dbo].[usp_demo_cursor_with_temp_table]              
AS              
BEGIN  
DECLARE @temp TABLE  (value1 varchar(5),value2 varchar(5),value3 INT,value4 varchar(1))

DECLARE @value1 varchar(5)
DECLARE @value2 varchar(5) 
DECLARE @value3 INT
DECLARE @value4 varchar(5)

DECLARE check_data_cursor CURSOR FOR 

select distinct value1,value2,value3,value4 from table_name where status = 'A'

OPEN check_data_cursor

FETCH NEXT FROM check_data_cursor INTO @value1,@value2,@value3,@value4

WHILE (@@FETCH_STATUS <> -1)

BEGIN
-- any business logic + temp inseration 

insert into @temp values (@tickerCode,@quarter,@financial_year,@status)
 END 

 FETCH NEXT FROM check_data_cursor  INTO @value1,@value2,@value3,@value4
 END

 CLOSE check_data_cursor

 DEALLOCATE check_data_cursor

 -- to view temp data

 select * from @temp          

END

【讨论】:

    【解决方案3】:

    已编辑:这应该有助于控制价格。由于价格来自不同的Select 声明,您可能需要在此处使用join

    INSERT INTO @Temp (Quantity, Price)
    (SELECT AMOUNT FROM LG_001_01_ORFLINE 
    WHERE LINETYPE    = 0 
    AND ORDFICHEREF = (SELECT TOP 1 LOGICALREF FROM LG_001_01_ORFICHE WHERE GUID='EEB44E72-3717-4F5B-8F7E-6A36EB38EA22' ORDER BY LINENO_ ASC)) T1
    JOIN 
    (SELECT ORG_PRICE FROM LG_XT002001_001 XT002 WHERE XT002.ORF_GUID='EEB44E72-3717-4F5B-8F7E-6A36EB38EA22' ORDER BY ORFLINE_NO ASC) T2
    ON T1.Primary_Key = T2.Primary_Key
    

    【讨论】:

      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      • 2014-01-24
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      相关资源
      最近更新 更多