假设我有一个名为@tblTemp
的表格,如下所示:
DECLARE @tblTemp TABLE
(
Id INT NOT NULL IDENTITY,
Name VARCHAR(MAX) NOT NULL,
ParentId INT NULL
)
我的XML结构(分配给@Xml
)是:
<Data>
<MyRow Name="I am the Parent"/>
<MyRow Name="I am the child" ParentName="I am the Parent"/>
</Data>
问题:是否可以在同一查询中插入ParentId
列?
SQL脚本
INSERT INTO @tblTemp ([Name], [ParentId])
SELECT
Rw.value('@Name','VARCHAR(MAX)'), -- Name
(SELECT [Id] -- Select ID From Parent Name
FROM @tblTemp AS [TT]
WHERE [TT].[Name] = Rw.value('@ParentName', 'VARCHAR(MAX)'))
FROM
@Xml.nodes('Data/MyRow') AS Data(Rw)
SELECT *
FROM @tblTemp AS [TT]
该脚本会将NULL
插入ParentId
列,因为我怀疑先前的插入尚未提交,因此该表将为空。
替代方案:如果无法在同一查询中插入ParentId
列,那么我的替代方法是执行插入,然后在需要时更新表。
答案 0 :(得分:1)
试试这样:
public class AndroidLauncher extends AndroidApplication {
private AdView adView;
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
RelativeLayout layout = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
layout.setLayoutParams(params);
View gameView=initializeForView(new BuckyRun(), config);
RelativeLayout.LayoutParams gameViewParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
gameViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
gameViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
gameView.setLayoutParams(gameViewParams);
layout.addView(gameView);
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId("secret");
AdRequest.Builder adRequestBuilder = new AdRequest.Builder();
adView.loadAd(adRequestBuilder.build());
RelativeLayout.LayoutParams topParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
topParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,RelativeLayout.TRUE);
topParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
layout.addView(adView, topParams);
adView.setBackgroundColor(android.graphics.Color.TRANSPARENT);
setContentView(layout);
}
@Override
protected void onResume() {
super.onResume();
adView.resume();
}
@Override
protected void onPause() {
super.onPause();
adView.pause();
}
@Override
protected void onDestroy() {
super.onDestroy();
adView.destroy();
}
结果
DECLARE @tblTemp TABLE
(
Id INT NOT NULL,
Name VARCHAR(MAX) NOT NULL,
ParentId INT NULL
)
DECLARE @xml XML=
N'<Data>
<MyRow Name="I am the Parent"/>
<MyRow Name="I am the child" ParentName="I am the Parent"/>
<MyRow Name="another child" ParentName="I am the Parent"/>
<MyRow Name="baby" ParentName="I am the child"/>
</Data>';
WITH DerivedTable AS
(
SELECT r.value(N'@Name',N'nvarchar(max)') AS [Name]
,r.value(N'@ParentName',N'nvarchar(max)') AS [ParentName]
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNmbr
FROM @xml.nodes(N'/Data/MyRow') AS A(r)
)
,recCTE AS
(
SELECT 1 AS Lvl
,[Name]
,[ParentName]
,RowNmbr
,CAST(NULL AS BIGINT) AS ParentRowNmbr
,CAST(N'' AS NVARCHAR(MAX)) AS [ParentPath]
FROM DerivedTable
WHERE ParentName IS NULL
UNION ALL
SELECT r.Lvl+1
,t.[Name]
,t.[ParentName]
,t.RowNmbr
,r.RowNmbr
,r.[ParentPath]+t.[ParentName]+N'|'
FROM DerivedTable AS t
INNER JOIN recCTE AS r ON r.[Name]=t.[ParentName]
)
--Use this SELECT to see all columns returned by the recursive CTE
--SELECT * FROM recCTE
INSERT INTO @tblTemp(ID,[Name],ParentId)
SELECT RowNmbr, [Name],ParentRowNmbr
FROM recCTE;
SELECT * FROM @tblTemp;
简短说明:
第一个CTE会将值读取为派生表,并使用Id Name ParentId
1 I am the Parent NULL
2 I am the child 1
3 another child 1
4 baby 2
将每行的运行编号作为ID。
第二个CTE递归地沿着道路行进
结果可以直接插入到您的表格中。
<强>注意强>
我将您的表从ROW_NUMBER()
更改为普通的INT列。您可以先使用ID is IDENTITY
获取最高的现有ID,然后将其添加到第一个CTE中的SELECT MAX(ID)
。否则可能会发生ROW_NUMBER()
给出的ID与ROW_NUMBER()
给出的ID不同。