Дмитрий Ковальский: мне нужно получить из БД записи из основной таблицы и все дочерние для каждой записи из основной таблицы. Сделать одним запросом можно это с помощью LEFT OUTER JOIN с двумя таблицами. Как писал выше, получается огромное кол-во дублирующихся записей. А если добавить ещё одну таблицу, то там вообще мега много строк выдает запрос. В итоге пришлось сделать 3 запроса, первый получает данные из основной таблицы и кладёт айдишники полученных записей во временную таблицу. Второй запрос получает все дочерние записи для каждого айдишника из временной таблицы, третий так же. А как по другому мне получив данные заполнить ими экземпляры C# классов?
Вот в этом вопросе более-менее понятно описано, что я хочу сделать. И мой же ответ, как это я решил. Опасно ли выполнять такой код в С# + T-SQL? Или каким способом можно написать по-другому?
Временную таблицу я создаю и именую её уникально в каждом вызове метода класса в C# коде, который работает с БД. То есть GetData() - создаётся временная таблица с уникальным именем. Раньше она создавалась в транзакции. Сейчас я вынес из транзакции. Если возникнет исключение, то она не удалится, как раньше. А удалится, когда я отключусь от БД.
Спасибо конечно, но вы так и не ответили на вопрос. У меня в C# коде создана транзакция и выполняются 3 запроса в этой транзакции. Пришлось создать глобальную временную таблицу, чтобы из C# кода получив в первом запросе данные не вызывать в цикле для каждой полученной записи получение записи из дочерней таблицы по ID записи родителя (каждая запись, полученная в первом запросе). Это как альтернатива тройному JOIN. Если у меня в БД 1 запись в основной таблице (родитель) и по 10 записей в двух дочерних таблицах, то соединив я получу на выходе 100 записей, а не 20, как хотелось бы.
В итоге сделал через глобальную временную таблицу, просто генерирую GUID и присоединяю к имени временной таблицы и ограничению первичного ключа. В конце. после выполнения третьего запроса удаляю таблицу. Всё работает. Наверное, так быстрее, чем собрать сначала из C# кода выполнив первый запрос, а потом в цикле получать по айди записи из дочерних таблиц.
Мда... Сделал с временной таблицей. В ms sql management studio всё работает в пределах одной транзакции. В C# коде нет. Пишет при вызове второго запроса: Invalid object name '#GroupIDs'
"Если у вас было 10 записей с REPLICATED =-10 (минус!), то до первого обновления подзапрос выдаст записи с 1 по 5, а после него с 6 по 10."
Это по какой причине? Как вообще значение REPLICATED влияет на возвращаемый запросом результат?
Ульрих: у меня та же идея появилась. Главное разобраться, как собрать проект: tishion.github.io/QCefView Ибо не собирается в 2015 студии. Может пути к Qt неправильно указаны, не знаю.
Да, вести будет он. Как мне сказали, там будет "открытое обучение". Идёт запись, а преподаватель в классе. Ему уже можно задавать вопросы. Я так подумал, так даже эффективнее, ибо можно что неясно перемотать. Все записи доступны в течении 3 месяцев, а поддержка в течении 6-ти месяцев. В общем, надо уже решать, егодня начинаются занятия, не уверен стоит ли заморачиваться, не проще ли самому выучить да сдать экзамены. Так-то стоит немало у них учёба. Деньги есть, но сколько бы их не было, неохота необдуманно их потратить.
Да как сказать. Какие-то знания от 2008 очень даже пригодятся. Понял, в общем, эти курсы лишь подготовка к экзамену. А сдаёшь когда экзамены, там много надо по-английски балакать? Или можно просто читать вопросы, да отвечать на них на компьютере?
Артем Каретников: Ничего причёсывать не нужно. Это пример, чтобы можно было выложить на форум, в реальном проекте примерно так же, но чуть по другому.
Поле Name ни о чём не говорит, в том контексте, в котором оно используется в MS SQL никаких проблем его использование не вызывает и не вызовет.
Ой, не смешите, пожалуйста, какую работу? Один запрос? Да я из личного интереса в разы больше работы выполнял, когда другим людям по C# помогал на другом форуме (с 2010 года там). Много с кем познакомился благодаря этому и даже устроился на первую работу именно благодаря помощи другим людям.
Тут работы: открыть Management Studio, создать пустую БД, скопировать мой код по созданию таблиц и заполнению данными, выполнить запрос, и набросать за 1 минуту новый вариант запроса. Какие баксы? Смысл тогда тут на форуме сидеть? Чтобы найти клиента на простом вопросе?
Артем Каретников: спасибо за информацию, но понимаете, меня интересует конкретный рабочий код. Всё это в теории я и сам знаю, что можно как-то так, а можно как-то и так. Но у меня 3 связанных запроса там, и если есть вариант покруче, то я бы не против его увидеть в виде работающего кода. В принципе, я для этой цели и привёл весь код в вопросе. Тут минимум телодвижений, скопировать код и набросать запрос, если время есть.
"Вот ваши три записи, любые несинхронизированные"
Вот это не понял вообще. О чём вы? Это намёк, что мои 3 SQL запроса в одном нужно как-то синхронизировать? Или что?
То есть в группе 1 - 3 человека, в группе 2 - 5 человек, в группе 3 - 1 человек. В итоге я должен получить 9 записей. То есть 3 группы и всех людей в каждой группе.
К сожалению тот вариант, который вы предложили немного не так работает, иначе такой изврат бы я не городил. То что вы предложили может выбрать 3 записи, 2 из которых это группа 1 и 2 человека из неё, что верно, а вторая группа будет содержать в себе только одного человека, а должа всех, не важно 2 их или 1000 (в реале не более 10 может быть).
Вот ваш код, работающий на моих данных:
SELECT TOP(3)
g.GroupID,
g.Name AS GroupName,
g.Replicated,
u.UserID,
u.Name AS UserName FROM Groups g
LEFT JOIN Users u ON u.GroupID = g.GroupID
WHERE Replicated <> 1;
sim3x: меня интересует как конкретно можно сделать по другому. Конкртеный код. Я сделал всё, чтобы любому было легко и просто показать этот реальный код. Всё для тестов готово, просто пример бы хотел увидеть.
Вот в этом вопросе более-менее понятно описано, что я хочу сделать. И мой же ответ, как это я решил. Опасно ли выполнять такой код в С# + T-SQL? Или каким способом можно написать по-другому?