#c# #sql #sql-server
Вопрос:
Я подумал, что, возможно, будет лучше задать этот вопрос по-другому и сосредоточиться на конкретной части, с которой у меня сейчас проблема.
Итак, у меня есть этот первый запрос, который я буду использовать:
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'";
Отсюда я хочу сохранить значения идентификаторов в качестве скалярной переменной, как это будет использоваться во 2-м запросе ниже:
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».
Что я буду пытаться сделать, так это использовать оба этих запроса для создания таблицы данных. Затем они будут использоваться для создания csv-файла с использованием csvhelper. Столбцы для этого файла взяты из файла 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; } }
So the first query will get the values for the columns: ItemID, ItemDetailID, Status, Number, Title, CreatedDate and WithDrawnDate.
The second query will get the value for LastModifiedDate. There will be a couple other queries for the rest but for now I am focusing on just getting this working with the first 2.
Как вы сможете видеть, в запросе LastModifiedDate также есть столбец ItemId, что я хочу сделать, так это сопоставить дату последнего изменения по идентификаторам. Итак, в качестве примера, если бы в 1-м запросе был идентификатор 245, я хотел бы получить значение из второго запроса, где идентификатор также равен 245, и поместить его в ту же строку таблицы данных, если это имеет смысл?
Так как же я могу это сделать? Я предполагаю, что мне нужно найти способ хранения идентификаторов из 1-го запроса, но я не уверен, что это лучший способ сделать это.
Я уже пробовал это:
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; }
но я чувствую, что ошибаюсь в этом, так как кажется, что в таблице данных хранится только 1-й запрос
Комментарии:
1. Какие СУБД вы используете?
2. Я использую Microsoft SQL Server, вы это имеете в виду?
Ответ №1:
Я не уверен, как я могу объединить эти запросы
Вам необходимо провести рефакторинг SQL для вывода соответствующих объединенных данных, которые могут быть преобразованы в CSV. Поместите его в хранимую процедуру и вставьте данные в свою программу, чтобы вывести их в CSV.
Комментарии:
1. Я вроде как понимаю, о чем вы говорите, но я не уверен, как это сделать. У вас случайно нет ссылки на хороший пример для чего-то подобного?
2. Вам придется индивидуально изучить, что делать с каждой из парадигм кодирования, которые вы ищете, и создать свой код. Нет ни одного волшебного примера, о котором вы, кажется, просите…исследуйте, а затем, если у вас есть отдельные проблемы, спросите по каждому из них в отдельности, а не все вместе. Другими словами, вам нужно сосредоточиться на этом вопросе и исследовать каждую область. глоссарий
3. Я не искал идеального примера того, что я пытаюсь сделать, просто что-то, что помогло бы объяснить ваш ответ
Ответ №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 ;";