将 id 值存储为标量变量,然后在第二个查询中使用
Posted
技术标签:
【中文标题】将 id 值存储为标量变量,然后在第二个查询中使用【英文标题】:Store id values as scalar variable to then use in 2nd query 【发布时间】:2022-01-01 06:55:23 【问题描述】:我认为最好以不同的方式提出这个问题,并专注于我目前遇到问题的特定部分。
所以我有了第一个要使用的查询:
private const string Items = @"
SELECT
id.ItemId, id.ItemDetailID, id.Status, id.Number
, id.Title, id.CreatedDate, id.WithdrawnDate
, RevisionNumber = id.MajorRevisionNumber + ISNULL(id.RevisionNumberOffset, 0)
FROM AgilityItemView v
JOIN ItemDetail id
ON id.ItemDetailID = v.ItemDetailId
WHERE id.[Status] in ('Released', 'Withdrawn')
AND V.VersionRank = 1 AND V.[Type] = 'Document'";
从这里我想做的是将 id 值存储为标量变量,因为这将在下面的第二个查询中使用:
private const string LastModifiedDate = @"
WITH History AS (
SELECT id.ItemID, id.ItemDetailID, ih.ActionedDate
, ROW_NUMBER() OVER(PARTITION BY id.ItemID ORDER BY ih.ActionedDate DESC) AS vn
FROM AgilityItemView v
JOIN ItemDetail id
ON id.ItemDetailID = v.ItemDetailId
JOIN ItemHistory ih
ON ih.ItemDetailID = id.ItemDetailID
WHERE id.[Status] in ('Released', 'Withdrawn')
AND V.VersionRank = 1 AND V.[Type] = 'Document'
AND ih.Action in (
'Create','Edit','ItemCreatedByChanged'
, 'ItemCustomPropertiesChanged','ItemNumberChanged','ItemRoleChanged'
, 'ItemTitleChanged','Release','Restore'
, 'ReturnToDraft','Revise','Withdraw'
)
)
SELECT ItemId, LastModifiedDate = ActionedDate
FROM History
WHERE vn = 1
AND ItemId = @ItemID";
如您所见,标量变量是“@ItemID”。
我将尝试使用这两个查询来创建数据表。然后这些将用于使用 csvhelper 创建一个 csv 文件。此文件的列来自 ExtractDocument.cs 文件。
public record ExtractDocument
public Guid ItemId get; init;
public string FileType get; init;
public string Status get; init;
public string Number get; init;
public string Title get; init;
public string Function get; init;
public string Discipline get; init;
public string Country get; init;
public string Asset get; init;
public string Language get; init;
public string URLLink get; init;
public string SubmitFeedback get; init;
public string ViewItemLink get; init;
public string CreatedDate get; init;
public DateTime? ReleasedDate get; init;
public string? WithdrawnDate get; init;
public DateTime LastModifiedDate get; init;
public int RevisionNumber get; init;
public string Author get; init;
public string Verifier get; init;
public string Reviewer get; init;
public string Approver get; init;
public string SecurityGroup get; init;
所以第一个查询将获取以下列的值:ItemID、ItemDetailID、Status、Number、Title、CreatedDate 和 WithDrawnDate。
第二个查询将获取 LastModifiedDate 的值。剩下的还有一些其他的查询,但现在我只专注于让前 2 项工作。
您将能够看到 LastModifiedDate 查询中还有一个 ItemID 列,我要做的是通过 id 匹配上次修改日期。例如,如果第一个查询的 id 为 245,我想要第二个查询的值,其中 id 也是 245,如果有意义的话,将其放在数据表的同一行中?
那么我该怎么做呢?我假设我需要找到一种方法来存储第一个查询中的 id,但我不确定最好的方法。
我试过这个:
private DataTable GetData(string itemsQuery, string modifiedData, string roleHoldersData, string customPropertiesData, ExtractDocument extract)
var dt = new DataTable();
var ds = new DataSet();
using var connection = new SqlConnection(_connectionString);
using var cnn = new SqlCommand(itemsQuery, connection);
var adapter = new SqlDataAdapter();
adapter.SelectCommand = cnn;
adapter.Fill(ds, "Table(0)");
adapter.SelectCommand.CommandText = modifiedData;
cnn.Parameters.AddWithValue("@ItemID", extract.ItemId);
adapter.Fill(ds, "Table(1)");
ds.Tables[0].Merge(ds.Tables[1]);
dt = ds.Tables[0];
adapter.Fill(dt);
return dt;
但我觉得我对此不太满意,因为它似乎只是将第一个查询存储在数据表中
【问题讨论】:
您使用的是哪个 dbms? 我一直在使用 Microsoft SQL Server,您是这个意思吗? 【参考方案1】:我不确定如何组合这些查询
您需要重构 SQL 以输出正确的联合数据,这些数据可以转换为 CSV。将其放入存储过程中,并将数据拉入您的程序以将其输出为 CSV。
【讨论】:
我可以理解你在说什么,但我不知道该怎么做。你碰巧有一个这样的好例子的链接吗? 您必须单独研究在您寻求的每个编码范例上要做什么并创建您的代码。似乎没有一个神奇的例子是你要求的......研究然后如果你有个别问题,然后单独询问每个问题,而不是一起询问。换句话说,您需要关注这个问题并研究每个领域。总帐 我不是在寻找一个完美的例子来说明我正在尝试做的事情,只是为了帮助解释你的答案【参考方案2】:因此,在进行了更多研究之后,似乎最好的方法是将查询合并起来,这样就可以完成我想做的事情,而不是 4 个较小的查询。
这是我最终得到的结果:
private const string ExtractData = @"
WITH ExtractData AS (
SELECT id.ItemID, id.ItemDetailID, id.Status, id.Number,
id.Title, id.CreatedDate, id.WithdrawnDate, id.ReleaseDate, ih.ActionedDate,
RevisionNumber = id.MajorRevisionNumber + ISNULL(id.RevisionNumberOffset, 0), OwnershipRoleTitle = IOR.Title,
HolderTitle = P.Title, CustomPropertyTitle = cp.Title, cpi.ItemTitle
, ROW_NUMBER() OVER(PARTITION BY id.ItemID ORDER BY ih.ActionedDate DESC) AS vn
FROM AgilityItemView v
JOIN ItemDetail id
ON id.ItemDetailID = v.ItemDetailId
JOIN ItemHistory ih
ON ih.ItemDetailID = id.ItemDetailID
JOIN dbo.ItemDetailOwnershipRole IDOR
ON Id.ItemDetailID = IDOR.ItemDetailID
JOIN dbo.ItemOwnershipRole IOR
ON IDOR.ItemOwnershipRoleID = IOR.ItemOwnershipRoleID
JOIN dbo.ItemDetailOwnershipRoleHolder IDOH
ON IDOH.ItemDetailOwnershipRoleID = IDOR.ItemDetailOwnershipRoleID
JOIN dbo.AgilityItemView P
ON IDOH.ItemOwnershipRoleHolderItemID = P.ItemID and p.VersionRank = 1
JOIN CustomPropertyItemReference cpir
ON cpir.ItemDetailID = id.ItemDetailID
JOIN CustomPropertyItem cpi
ON cpi.CustomPropertyItemID = cpir.ReferenceItemID
JOIN CustomProperty cp
ON cp.CustomPropertyID = cpi.CustomPropertyID
WHERE id.[Status] in ('Released', 'Withdrawn')
AND V.VersionRank = 1 AND V.[Type] = 'Document'
AND ih.Action in (
'Create','Edit','ItemCreatedByChanged'
, 'ItemCustomPropertiesChanged','ItemNumberChanged','ItemRoleChanged'
, 'ItemTitleChanged','Release','Restore'
, 'ReturnToDraft','Revise','Withdraw'
)
AND IOR.Title IN ('Reviewer', 'Drafter', 'Owner', 'Approver')
AND cp.Title in (
'Office Location', 'Governence', 'Type'
, 'HSEQ', 'Approver'
)
)
SELECT ItemID, ItemDetailId, Status, Number, Title, CreatedDate, ReleaseDate,
WithdrawnDate, LastModifiedDate = ActionedDate, RevisionNumber, OwnershipRoleTitle, HolderTitle,
CustomPropertyTitle, ItemTitle
FROM ExtractData
WHERE vn = 1
;";
【讨论】:
以上是关于将 id 值存储为标量变量,然后在第二个查询中使用的主要内容,如果未能解决你的问题,请参考以下文章
从存储过程完成的第一个插入中提取 id 以在第二个存储过程上使用的麻烦
在第二个查询中查询两个单独的表传递结果,同时仅在第二个查询返回 null 时保留第一个查询的结果