Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 从以前的记录继承值_Tsql - Fatal编程技术网

Tsql 从以前的记录继承值

Tsql 从以前的记录继承值,tsql,Tsql,在下表中,除了值之外的所有字段都是表上唯一索引的一部分。仅当记录具有空值时,我才希望将值从具有ValueNULL的记录继承到下一个修订记录(请参见下面的示例): Var[n]Value字段使用varchar,我的表中可能有1-n个Var[n]Value字段 资料来源: Document# Revision Project# config# Var1Value Var2Value 1744 1 2 1 NULL NULL 1744 2 2

在下表中,除了值之外的所有字段都是表上唯一索引的一部分。仅当记录具有空值时,我才希望将值从具有
ValueNULL
的记录继承到下一个修订记录(请参见下面的示例):

Var[n]Value
字段使用varchar,我的表中可能有1-n个
Var[n]Value
字段

资料来源:

Document#   Revision    Project#    config# Var1Value   Var2Value
1744    1   2   1   NULL    NULL
1744    2   2   1   NULL    NULL
1744    3   2   1   Tit1    ABC
1744    4   2   1   Tit2    ABD
1744    5   2   1   NULL    NULL
1744    6   2   1   NULL    SDC
1744    7   2   1       AS
1744    8   2   1   Tit3    NULL
所需结果(注意修订记录5和6的更改
var1value
和5,8的更改
var2value
):

你知道如何用SQL来处理它吗

请告知

我尝试了以下方法:

declare @TableName as VarChar(32) = 'MYTABLE'
declare @SetClause as VarChar(1024)
declare @LWhereClause as VarChar(1024)
declare @RWhereClause as VarChar(1024)

-- Get the column names.
select Column_Name
  into #Columns
  from Information_Schema.Columns
  where Table_Name = @TableName and Column_Name like 'Var%'
--select * from #Columns

-- Assemble the clauses we'll need for the   UPDATE   statement.
declare @ColumnName as VarChar(32)
while ( @@RowCount > 0 )
  begin
  select top 1 @ColumnName = Column_Name
    from #Columns
    order by Column_Name
  set @SetClause = case when @SetClause is NULL then '' else @SetClause + ', ' end +
    @ColumnName + ' = Coalesce( L.' + @ColumnName + ', R.' + @ColumnName + ' )'
  set @LWhereClause = case when @LWhereClause is NULL then '' else @LWhereClause + ' or ' end +
    'L.' + @ColumnName + ' is NULL'
  set @RWhereClause = case when @RWhereClause is NULL then '' else @RWhereClause + ' or ' end +
    'R.' + @ColumnName + ' is not NULL'
  delete from #Columns
    where Column_Name = @ColumnName
  end

--select @SetClause, @LWhereClause, @RWhereClause

-- Put together the   UPDATE   statement.
declare @Update as nVarChar(max)
set @Update=''
set @Update=@Update +
  'update L set ' + @SetClause + ' from ' + @TableName +
  ' as L inner join ' + @TableName + ' as R on R.DocId = L.DocId and R.Rev = L.Rev - 1 and R.Proj = L.Proj and R.Conf = L.Conf' +
  ' where ( ' + @LWhereClause + ' ) and ( ' + @RWhereClause + ' )'

-- Put together the entire loop.  This needs work.
declare @Loop as nVarChar(max)
set @Loop =''
set @Loop=@Loop+
  '@declare Eleanor as Int = 42;
    while ( @Eleanor > 0 ) ' 
    + @Update + ' 
    set @Eleanor = @@RowCount
    end'

--select @Loop

-- Execute it.
exec @Loop

drop table #Columns
我在exec循环中得到以下错误。为什么要截断nvarchar字符串

味精203,16级,状态2,第53行
名称'@声明埃莉诺为Int=42
而(@Eleanor>0)更新L集合variable104=聚结(L.variable104,R.variable104),variable105=聚结(L.variable105,R.variable105),variable106=聚结(L.variable106,R.variable106),variable107=聚结(L.variable107,R.variable107),variable112=聚结(L.variable112,R.variable112),variable116=聚结(L.variable116,R.variable116),variable119=聚结(L.variable119,R.variable119),variable120=聚结(L.variable120,R.variable120),variable121=聚结(L.variable121,R.variable121),variable122=聚结(L.variable122,R.variable122),variable124=Co'不是有效标识符


<> > >编辑< /强>:请原谅,但我没有考虑变量列。

此查询将检索在
YourTable
中定义的列:

select Column_Name from Information_Schema.Columns where Table_Name = 'YourTable'
此后,您需要构建一个动态查询并执行它。您可以为每个单独的列编写如下所示的代码,或者一次性处理所有列


动态构建查询是一个有点乏味的过程

declare @TableName as VarChar(32) = 'YourTable'
declare @SetClause as VarChar(1024)
declare @LWhereClause as VarChar(1024)
declare @RWhereClause as VarChar(1024)

-- Get the column names.
select Column_Name
  into #Columns
  from Information_Schema.Columns
  where Table_Name = @TableName and Column_Name like 'Var%'
select * from #Columns

-- Assemble the clauses we'll need for the   UPDATE   statement.
declare @ColumnName as VarChar(32)
while ( @@RowCount > 0 )
  begin
  select top 1 @ColumnName = Column_Name
    from #Columns
    order by Column_Name
  set @SetClause = case when @SetClause is NULL then '' else @SetClause + ', ' end +
    @ColumnName + ' = Coalesce( L.' + @ColumnName + ', R.' + @ColumnName + ' )'
  set @LWhereClause = case when @LWhereClause is NULL then '' else @LWhereClause + ' or ' end +
    'L.' + @ColumnName + ' is NULL'
  set @RWhereClause = case when @RWhereClause is NULL then '' else @RWhereClause + ' or ' end +
    'R.' + @ColumnName + ' is not NULL'
  delete from #Columns
    where Column_Name = @ColumnName
  end

select @SetClause, @LWhereClause, @RWhereClause

-- Put together the   UPDATE   statement.
declare @Update as VarChar(4096) =
  'update L set ' + @SetClause + ' from ' + @TableName +
  ' as L inner join ' + @TableName + ' as R on R.DocId = L.DocId and R.Rev = L.Rev - 1 and R.Proj = L.Proj and R.Conf = L.Conf' +
  ' where ( ' + @LWhereClause + ' ) and ( ' + @RWhereClause + ' )'

-- Put together the entire loop.  This needs work.
declare @Loop as VarChar(4096) =
  '@declare Eleanor as Int = 42; ...' + @Update + '...'

select @Loop

-- Execute it.
exec @Loop

drop table #Columns

这里有一种可怕的方法是基于版本号密集:

declare @Docs as Table ( DocId Int, Rev Int, Proj Int, Conf Int, Var1 VarChar(10) Null, Var2 VarChar(10) Null )

insert into @Docs ( DocId, Rev, Proj, Conf, Var1, Var2 ) values
  ( 1744, 1, 2, 1, NULL, NULL ),
  ( 1744, 2, 2, 1, NULL, NULL ),
  ( 1744, 3, 2, 1, 'Tit1', 'ABC' ),
  ( 1744, 4, 2, 1, 'Tit2', 'ABD' ),
  ( 1744, 5, 2, 1, NULL, NULL ),
  ( 1744, 6, 2, 1, NULL, 'SDC' ),
  ( 1744, 7, 2, 1, '', 'AS' ), -- The example data for this row is unclear.
  ( 1744, 8, 2, 1, 'Tit3', NULL )

select * from @Docs

declare @Eleanor as Int = 42
while ( @Eleanor > 0 )
  begin
  update L
    set Var1 = Coalesce( L.Var1, R.Var1 ), Var2 = Coalesce( L.Var2, R.Var2 )
    from @Docs as L inner join
      @Docs as R on R.DocId = L.DocId and R.Rev = L.Rev - 1 and R.Proj = L.Proj and R.Conf = L.Conf
    where ( L.Var1 is NULL or L.Var2 is NULL ) and ( R.Var1 is not NULL or R.Var2 is not NULL )
  set @Eleanor = @@RowCount
  end

select * from @Docs
以下文件的准确副本:
p、 s:我没有评论的特权。所以我写了答案。

修订号总是密集的吗?我不知道你说的密集是什么意思?修订是唯一索引的一部分(由文档#、修订、项目#和配置#组成)。我只需要根据以前修订的val[n]进行更新如果该值不为null,且相应当前修订的var[n]值为null,“密集”指的是一系列没有间隙的值。如果修订号密集,则给定一个大于1的值R,您可以始终指望表中的值R-1(对于同一文档和项目)。如果修订不密集,那么您需要继续搜索小于R的最大值。甚至可能没有修订版本!好的,我明白了。修订版本密集。谢谢Mahmood,我正在寻找一种动态方法,以便在我的示例中对n个varvalue字段进行查询。您能提供一个这样做的示例吗?如何进行在上面的例子中,我使用了var1和var2,但是当运行我的程序时,它可能运行在一个有100个变量的数据库上(即var100)在某些情况下,只有很少的变量。我正在寻找一种动态的方法来处理它,即使它运行了几个小时。我确实编辑了我的答案,以包含关于动态构建查询的附加信息。
declare @Docs as Table ( DocId Int, Rev Int, Proj Int, Conf Int, Var1 VarChar(10) Null, Var2 VarChar(10) Null )

insert into @Docs ( DocId, Rev, Proj, Conf, Var1, Var2 ) values
  ( 1744, 1, 2, 1, NULL, NULL ),
  ( 1744, 2, 2, 1, NULL, NULL ),
  ( 1744, 3, 2, 1, 'Tit1', 'ABC' ),
  ( 1744, 4, 2, 1, 'Tit2', 'ABD' ),
  ( 1744, 5, 2, 1, NULL, NULL ),
  ( 1744, 6, 2, 1, NULL, 'SDC' ),
  ( 1744, 7, 2, 1, '', 'AS' ), -- The example data for this row is unclear.
  ( 1744, 8, 2, 1, 'Tit3', NULL )

select * from @Docs

declare @Eleanor as Int = 42
while ( @Eleanor > 0 )
  begin
  update L
    set Var1 = Coalesce( L.Var1, R.Var1 ), Var2 = Coalesce( L.Var2, R.Var2 )
    from @Docs as L inner join
      @Docs as R on R.DocId = L.DocId and R.Rev = L.Rev - 1 and R.Proj = L.Proj and R.Conf = L.Conf
    where ( L.Var1 is NULL or L.Var2 is NULL ) and ( R.Var1 is not NULL or R.Var2 is not NULL )
  set @Eleanor = @@RowCount
  end

select * from @Docs