Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / WinForms, .Net Framework |
![]() ![]() |
Mixon Member Откуда: Сообщений: 331 |
День добрый! Подскажите есть ли способ получить имена полей типа Имя_Таблицы.Имя_Поля для запросов типа: Select * from T и Select * from T as t Left Join T2 as t2 ON t2.id=t.id_T2 ... Left Join TN as tn ON tn.id=tk.id_T2 |
29 май 18, 13:35 [21450068] Ответить | Цитировать Сообщить модератору |
Shocker.Pro Member Откуда: ->|<- :адуктО Сообщений: 21014 |
select * - зло Выбирай нужные поля и назначай им необходимые псевдонимы |
29 май 18, 13:51 [21450150] Ответить | Цитировать Сообщить модератору |
Cat2 Member Откуда: Petroskoi, Karjala Сообщений: 145676 |
Mixon, Где получить? |
29 май 18, 14:07 [21450231] Ответить | Цитировать Сообщить модератору |
Roman Mejtes Member Откуда: г. Пермь Сообщений: 3605 |
обычно за такие запросы типа: SELECT * FROM T у нас принято отправлять на доработку :) это очень плохая идея, особенно если в запросе много JOIN'ов, а 90% полей нафиг ненадо. Это может сильно замедлить запрос и в случае добавления полей поломать логику |
||
29 май 18, 14:14 [21450273] Ответить | Цитировать Сообщить модератору |
skyANA Member Откуда: Зеленоград Сообщений: 26878 |
+1 |
||
29 май 18, 14:25 [21450333] Ответить | Цитировать Сообщить модератору |
Сон Веры Павловны Member Откуда: Сообщений: 5303 |
И особенно, если у соединяемых таблиц есть поля с одинаковыми именами. Метаданные выборки (имена полей, их типы) получить несложно, если возврат метаданных поддерживается провайдером: DataTableReader.GetSchemaTable (если не поддерживается, вернется null), но вот какое поле результирующего набора относится к какой из соединяемых таблиц, не получить никак. |
||
29 май 18, 15:20 [21450622] Ответить | Цитировать Сообщить модератору |
hVostt Member Откуда: Сообщений: 16272 |
Соглашусь с тем, что за select * надо бить, но вот это не правда :)
Парсится первая строка результата запроса и получаем имена полей. |
||||
29 май 18, 15:22 [21450630] Ответить | Цитировать Сообщить модератору |
hVostt Member Откуда: Сообщений: 16272 |
Тьфу блин, прочитал «невозможно»... вот чукча. |
||||
29 май 18, 15:23 [21450633] Ответить | Цитировать Сообщить модератору |
Сон Веры Павловны Member Откуда: Сообщений: 5303 |
А если в селект-листе коррелированные подзапросы? |
||
29 май 18, 15:28 [21450654] Ответить | Цитировать Сообщить модератору |
Mixon Member Откуда: Сообщений: 331 |
Понимаю всеобщее негодование, всем спасибо. |
29 май 18, 15:39 [21450715] Ответить | Цитировать Сообщить модератору |
hVostt Member Откуда: Сообщений: 16272 |
Зависит от провайдера, как он на это отреагирует. Может и колонки с повторяющимися именами засунуть. |
||||
29 май 18, 15:42 [21450732] Ответить | Цитировать Сообщить модератору |
Roman Mejtes Member Откуда: г. Пермь Сообщений: 3605 |
Microsoft® SQL Server Transact-SQL ScriptDom Копать нужно в этом направлении, но лучше не копать |
29 май 18, 16:33 [21450994] Ответить | Цитировать Сообщить модератору |
Супер_Пав Member Откуда: Москва Сообщений: 397 |
var selectQuery = "Some sql query"; using (var sqlConn = new SqlConnection("ConnectionString")) { var sqlCmd = new SqlCommand(selectQuery , sqlConn); var sqlAdapter = new SqlDataAdapter(sqlCmd); var table = new DataTable(); sqlAdapter.Fill(table); //table.Columns - коллекция столбцов } |
29 май 18, 16:34 [21450996] Ответить | Цитировать Сообщить модератору |
Konst_One Member Откуда: Сообщений: 11493 |
ну и с чего вы решили, что у ТС MS SQL Server? |
29 май 18, 16:51 [21451107] Ответить | Цитировать Сообщить модератору |
buser Member Откуда: Санкт-Петербург Сообщений: 4479 |
Какая разница... постановка была "Имя_Таблицы.Имя_Поля" и селект со звездой... |
||
29 май 18, 16:59 [21451142] Ответить | Цитировать Сообщить модератору |
Сон Веры Павловны Member Откуда: Сообщений: 5303 |
Имя таблицы в пролете. Теоретически можно распарсить запрос, получить имена таблиц, последовательно вытащить из словарных таблиц базы имена колонок, и исходя из того, что при select * сначала выводятся колонки первой таблицы, потом второй, итд. в порядке расположения колонок таблицы, сформировать алиасы. Но вот что делать, если один из участников джойна - CTE или подзапрос? Учитывая, что тип БД не указан, можно вспомнить про тот же оракл, где джойны могут быть написаны в ансишном стиле, а могут в родном оракловом (имена таблиц через запятую во from, все предикаты соединений в секции where). В общем, чем решать задачу, тянущую на написание полноценного парсера SQL, лучше немного потрудиться пальцами, и по-человечески сформировать список выбираемых полей. Это намного, на 10 порядков проще. |
||||
29 май 18, 17:15 [21451218] Ответить | Цитировать Сообщить модератору |
Shocker.Pro Member Откуда: ->|<- :адуктО Сообщений: 21014 |
|
||
29 май 18, 17:34 [21451293] Ответить | Цитировать Сообщить модератору |
hVostt Member Откуда: Сообщений: 16272 |
Да не надо этого делать. Выполняешь любой запрос, потом смотришь на результат, который вернулся. Посмотри на исходники Dapper-а, который абсолютно любой запрос может вернуть как dynamic (внутри там будет IDictionary<string, object>), и никакая схема ему не нужна. |
||
29 май 18, 18:01 [21451407] Ответить | Цитировать Сообщить модератору |
Сон Веры Павловны Member Откуда: Сообщений: 5303 |
А к какой таблице какие колонки относятся - откуда взять? У ТС в постановке задачи было
А просто получить имена полей выборки - да, дело нехитрое, и способов для этого существует больше одного. Ну, и в случае наличия в разных соединяемых таблицах полей с одинаковыми именами будет весело (см. скриншот ниже). Если бы их не было, то к дапперовскому dynamic-результату можно было бы обращаться как-то так: using (var cnn = new SqlConnection("Data Source=.;Initial Catalog=stuff;Integrated Security=True")) { cnn.Open(); var data = cnn.Query(@" select 1 n, 'A' s union all select 2, 'B'"); foreach (var row in data) Console.WriteLine("{0}: {1}", row.n, row.s); } а в случае колонок с одинаковыми именами - только вот так: create table dbo.Test ( n int, s varchar(1) ) go insert into dbo.Test(n,s) values(1, 'A') go using (var cnn = new SqlConnection("Data Source=.;Initial Catalog=stuff;Integrated Security=True")) { cnn.Open(); var data = cnn.Query(@" select * from dbo.Test t1 join dbo.Test t2 on t2.n=t1.n join dbo.Test t3 on t3.n=t2.n join dbo.Test t4 on t4.n=t3.n "); foreach (var row in data) foreach(var kvp in row) Console.WriteLine("{0}: {1}", kvp.Key, kvp.Value); } - не позавидую тому, кому придется работать с такой кашей. В общем, явное перечисление выбираемых полей в селект-листе, и назначение алиасов для полей выборки с одинаковыми именами так, чтобы имя каждого поля в выборке было уникальным - залок отсутствия головной (и не только) боли в будущем. К сообщению приложен файл. Размер - 26Kb |
||||||
30 май 18, 07:16 [21452314] Ответить | Цитировать Сообщить модератору |
hVostt Member Откуда: Сообщений: 16272 |
Да, за звездочку в запросах лупашить подвернувшимся айпадом ![]() |
||
30 май 18, 10:50 [21452784] Ответить | Цитировать Сообщить модератору |
Все форумы / WinForms, .Net Framework | ![]() |