Сохраните значения идентификаторов в виде скалярной переменной, чтобы затем использовать их во 2-м запросе

#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  ;";