Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
o-o,

DECLARE @Str varchar(MAX) = ''

SELECT TOP 1000
@Str += Name + ' UNION ALL '
FROM sys.objects

SET @Str = SUBSTRING(@Str,0,LEN(@Str)-8)

PRINT LEN(@Str)

собрало 32564, но могу и тупить :)
11 июл 16, 17:57    [19396462]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
o-o
Guest
Kapadastra
o-o, Нужно выполнить их все, просто есть нюанс, он добавляются, удаляются и редактируются

пока вы их будете вычитывать, не отредактируют и не удалят.
но если вам аж надо заставить всех писателей подождать еще и результат выполнения вашего мега-юниона,
все засуньте в serializable-транзакцию.
11 июл 16, 17:58    [19396469]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Kapadastra
Member

Откуда:
Сообщений: 29
правильный проходящий.,
Есть одно но мое "Кунг-фу" гораздо слабее Вашего)))))
может Ваш вариант и будет работать, но "вкурить" я его пока не могу, спасибо что помогаете, буду "Курить" ваш вариант... надеюсь эффект будет)
11 июл 16, 18:02    [19396483]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
o-o
Guest
TaPaK
o-o,

DECLARE @Str varchar(MAX) = ''

SELECT TOP 1000
@Str += Name + ' UNION ALL '
FROM sys.objects

SET @Str = SUBSTRING(@Str,0,LEN(@Str)-8)

PRINT LEN(@Str)

собрало 32564, но могу и тупить :)

да, прикольно, собрало.
сейчас поищу, в чем подвох.
у нас недавно один такое собирал, тоже в varchar(max).
ни одно из слагаеных к varchar(max) не привел.
в результате пошел сие выполнять, а оно обрезано.
ровно 8000 символов.
привели первое слагаемое к varchar(max), собрало все как надо.
но в sys.objects вроде name nvarchar(128).
щас подумаю, спасибо за загадку
11 июл 16, 18:05    [19396500]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31431
Дедушка
Kapadastra
Дедушка, Это разные работающие селекты, относительно разные, поля все равно выводят одинаковые, разница в условиях. Когда я их копирую вручную и делаю юнион все работает.
Объединить надо в одну строку добавив между ними UNION .

как у вас select1 отделён от select2 в этом поле (GO, $$$, перевод строки)?
повторяется ли этот разделитель где-то ещё в тексте этого поля?
Не, у него один слект - это одна запись в таблице.
o-o
да, прикольно, собрало.
сейчас поищу, в чем подвох.
Подвох в том, что это недокументировано?
11 июл 16, 19:11    [19396770]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Kapadastra
Member

Откуда:
Сообщений: 29
TaPaK,
Спасибо большое) Ваше извращение то, что нужно, но выяснилось одно, но мое извращение оказывается в некоторых запросах содержит order by в конце запроса, и поэтому все вместе селекты не отрабатывают, теперь думаю как в в вашем извращении отрубать все что после order by включая order by)
А так спасибо
12 июл 16, 09:14    [19397915]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Kapadastra
Member

Откуда:
Сообщений: 29
Существует ли функция удалить в строке все от Order by до union? или указанное кол-во символов после order by включая его самого. Спасибо
12 июл 16, 10:09    [19398231]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
serpentariy
Member

Откуда:
Сообщений: 265
o-o
да, прикольно, собрало.
сейчас поищу, в чем подвох.
Ну дак @Str += это же @Str = @Str +, т.е. первое слагаемое varchar(max)
12 июл 16, 10:11    [19398240]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
o-o
Guest
Kapadastra
Существует ли функция удалить в строке все от Order by до union? или указанное кол-во символов после order by включая его самого. Спасибо

stuff + charindex('order ', YourField)
только еще и просто "order" забьет
(но може у вас и нет просто order-а)
12 июл 16, 10:12    [19398254]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
o-o
Guest
alexeyvg
Подвох в том, что это недокументировано?

недокументированность из другой оперы.
т.е. она имеется, но это не повод обрезать сбор в переменную в одном случае
и не обрезать в другом.
известное issue со сбором в переменную связано с ORDER BY,
когда все обрезается до одного слагаемого, ну так там в плане SORT.
а в описываемой мной ситуации обрезается до 8000 символов.
но тк у меня идеальная память, удалось найти.
вот код, который наклепал товарищ,
и который обрезается на 8000 символах,
если не приводить хотя бы одно из слагаемых в явном виде к varchar(max).
+
declare @v_ultimo_fine_mese varchar(8) = '20160222';
declare @v_sql varchar(max);

set @v_sql = 
             cast('insert into dbo.DO_Master_Pratiche_gestite_' as varchar(max)) + @v_ultimo_fine_mese + '_T ' +  -- comment 
             /*'insert into dbo.DO_Master_Pratiche_gestite_'  + @v_ultimo_fine_mese + '_T ' +*/                   -- uncomment this!!!!
             'select p.datarif,' +
                    '''==>'' as [Dati Pratica],' +
                    'p.NUM_PRAT,' +
                    'p.NDG,' +
                    'p1.ndg_orig,' +
                    'p1.DAARCHIVIARE,' +
                    'p1.[Da Archiviare],' +
                    'case when p1.DAARCHIVIARE = 0 then ''In Gestione'' else ''In Fine Gestione'' end as [Stato Pratica],' +
                    'p1.ARCHIVIATA,' +
                    'p1.DATARICMAN,' +
                    'year(p1.DATARICMAN) as AnnoRicMan,' + --update 1 rettifica pratiche ex workout
                    'month(p1.DATARICMAN) as MeseRicMan,' +
----------------------------------------------------------------------------------------------------------------------
-- dati tabelle IT
--             'd.DATARICMAN_DEGRADO as DATARICMAN_degrado, ' +
--             'isnull(d.ANNO_DEGRADO,0) as AnnoRicMan_D, ' +
--             'isnull(d.MESE_DEGRADO,0) as MeseRicMan_D, ' +
----------------------------------------------------------------------------------------------------------------------
                    'p1.DATADAARCHIV,' +
                    'p1.TIPOPRATIC,' +
                    'p1.[Tipo Pratica],' +
                    'p.GARANTI,' +
--                    '''no'' AS [Presenza Garanzie Consortili], ' +
                    '''==>'' as Portafogli,' +
                    'p.IDBanca,' +
                    'p.Mandante,' +
                    'p.cod_portafoglio,' +
                    'p.Portafoglio,' +
                    'null as Tipologia_Portafoglio,' +
                    '''==>'' as [Struttura Organizzativa], ' +
                    'p.CodDpt,' +
                    'p.Department,' +
                    'p.CodArea,' +
                    'p.Aree,' +
                    'p.codufficio,' +
                    'p.struttura,' +
                    'p.CodResponsabileStruttura,' +
                    'p.Head_of_Cluster,' +
                    'p.CodiceUtenza,' +
                    'p.TM_CoordAes_SostResp,' +
                    'p.CODRESPINT,' +
                    'p.AM_RP as [Responsabile Pratica],' +
--                    'p.[Data Assegnazione a GI], ' +
                    'i_pe.CODINDIVIDUO as CODINDIVIDUO_pe,' +
                    'i_pe.Individuo as Individuo_pe,' +
                    'p.CODRESPONS,' +
                    'p.GestoreOperativo as [Responsabile Operativo],' +
                    'ul.[Codice LE],' +
                    'ul.LE,' +
                    'ul.procedura,' +
                    'ul.tipoproc,' +
                    'ul.[Tipo Procedura],' +
                    'ul.Oltre_un_LE_presente,' +
                    'p.GestioneInterna,' +
                    'case when p2.NONREVOCABILE_AL_GESTORE = 0 then ''no'' else ''si'' end as [Non Revocabile al Gestore],' +
--                    'i.AES, ' +
                    '''==>'' as [Area Geografica],' +
                    'mreg.macroregione as Macroregione,' +
                    'reg.regione as Regione, ' +
                    'res.BB01_RES_PROVINCIA as Provincia,' +
                    'res.BB01_RES_CITTA as [Città],' +
                    'res.BB01_RES_CAP as cap,' +
                    '''==>'' as [Importo Crediti],' +
--p.[Saldo Conferimento],
--	CASE 
--WHEN p.[Saldo Conferimento] < 0						THEN 'a) <0k'
--WHEN ISNULL(p.[Saldo Conferimento],0) >= 0 and 
--		p.[Saldo Conferimento] <= 4000				THEN 'b) 0-4k'
--WHEN p.[Saldo Conferimento] <= 10000				THEN 'c) 4-10k'
--WHEN p.[Saldo Conferimento] <= 25000				THEN 'd) 10-25k'
--WHEN p.[Saldo Conferimento] <= 50000				THEN 'e) 25-50k'
--WHEN p.[Saldo Conferimento] <= 100000				THEN 'f) 50-100k'
--WHEN p.[Saldo Conferimento] <= 300000				THEN 'g) 100-300k'
--WHEN p.[Saldo Conferimento] <= 500000				THEN 'h) 300-500k'
--WHEN p.[Saldo Conferimento] <= 1000000				THEN 'i) 500-1.000k'
--WHEN p.[Saldo Conferimento] <= 1500000				THEN 'l) 1.000-1.500k'
--WHEN p.[Saldo Conferimento] <= 5000000				THEN 'm) 1.500-5.000k'
--ELSE 'n) >5.000k' 
--END AS 	[Range Saldo Conf],
                    'p.[Credito Contrattuale Conf],' +
                    'p.cap_contratto_i,' +
                    'p.cap_contratto_c,' +
                    'case ' +
                      'when p.[Credito Contrattuale Conf] < 0        then ''a) <0k'' ' +
                      'when isnull(p.[Credito Contrattuale Conf],0) >= 0 and ' +
                      'p.[Credito Contrattuale Conf] <= 4000       then ''b) 0-4k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 10000   then ''c) 4-10k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 25000   then ''d) 10-25k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 50000   then ''e) 25-50k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 100000  then ''f) 50-100k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 300000  then ''g) 100-300k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 500000  then ''h) 300-500k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 1000000 then ''i) 500-1.000k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 1500000 then ''l) 1.000-1.500k'' ' +
                      'when p.[Credito Contrattuale Conf] <= 5000000 then ''m) 1.500-5.000k'' ' +
                      'else ''n) >5.000k'' ' +
                    'end as [Range CC Conf], ' +
                    'isnull(c.[Saldo Contabile Conf], 0) as [Saldo Contabile Conf], ' +
                    'case ' +
                      'when p.[Credito Contrattuale Conf] = 0 and p.cap_contratto_i = 0 and p.cap_contratto_c = 0 then 0 ' +
                      'when p.[Credito Contrattuale Conf] = 0 and p.cap_contratto_i > p.cap_contratto_c           then 1 ' +
                      'when p.[Credito Contrattuale Conf] = 0 and p.cap_contratto_i < p.cap_contratto_c           then 0 ' +
                      'when p.[Credito Contrattuale Conf] < 0 and p.cap_contratto_i < 0 and p.cap_contratto_c = 0 then 1 ' +
                      'when p.[Credito Contrattuale Conf] < 0 and p.cap_contratto_i < 0 and p.cap_contratto_c > 0 then 0 ' +
                      'when p.[Credito Contrattuale Conf] < 0 and p.cap_contratto_i > 0 and p.cap_contratto_c < 0 then 1 ' +
                      'when p.[Credito Contrattuale Conf] > 0 and p.cap_contratto_i >= p.cap_contratto_c          then 1 ' +
                      'else 0 ' +
                    'end as [Prevalenza IPO conf], ' +
                    'case ' + 
                      'when p.[Credito Contrattuale Conf] = 0 and p.cap_contratto_i = 0 and p.cap_contratto_c = 0 then 0 ' +
                      'when p.[Credito Contrattuale Conf] = 0 and p.cap_contratto_i < p.cap_contratto_c           then 1 ' +
                      'when p.[Credito Contrattuale Conf] = 0 and p.cap_contratto_i > p.cap_contratto_c           then 0 ' +
                      'when p.[Credito Contrattuale Conf] < 0 and p.cap_contratto_i = 0 and p.cap_contratto_c < 0 then 1 ' +
                      'when p.[Credito Contrattuale Conf] < 0 and p.cap_contratto_i = 0 and p.cap_contratto_c > 0 then 1 ' +
                      'when p.[Credito Contrattuale Conf] < 0 and p.cap_contratto_i > 0 and p.cap_contratto_c < 0 then 0 ' +
                      'when p.[Credito Contrattuale Conf] < 0 and p.cap_contratto_i < 0 and p.cap_contratto_c = 0 then 0 ' +
                      'when p.[Credito Contrattuale Conf] > 0 and p.cap_contratto_i >= p.cap_contratto_c          then 0 ' +
                      'else 1 ' +
                    'end as [Prevalenza CHI conf], ' +
                    'p.CC, ' +
                    'p.CC_ipo, ' +
                    'p.CC_chi, ' +
                    'case ' +
                      'when p.CC = 0 AND p.CC_ipo = 0 and p.CC_chi = 0 then 0 ' +
                      'when p.CC = 0 and p.CC_ipo > p.CC_chi           then 1 ' +
                      'when p.CC = 0 and p.CC_ipo < p.CC_chi           then 0 ' +
                      'when p.CC < 0 AND p.CC_ipo < 0 and p.CC_chi = 0 then 1 ' +
                      'when p.CC < 0 AND p.CC_ipo < 0 and p.CC_chi > 0 then 0 ' +
                      'when p.CC < 0 AND p.CC_ipo > 0 and p.CC_chi < 0 then 1 ' +
                      'when p.CC > 0 AND p.CC_ipo >= p.CC_chi          then 1 ' +
                      'else 0 ' +
                    'end as [Prevalenza IPO attuale], ' +
                    'case ' +
                      'when p.CC = 0 AND p.CC_ipo = 0 and p.CC_chi = 0 then 0 ' +
                      'when p.CC = 0 and p.CC_ipo < p.CC_chi           then 1 ' +
                      'when p.CC = 0 and p.CC_ipo > p.CC_chi           then 0 ' +
                      'when p.CC < 0 AND p.CC_ipo = 0 and p.CC_chi < 0 then 1 ' +
                      'when p.CC < 0 AND p.CC_ipo = 0 and p.CC_chi > 0 then 1 ' +
                      'when p.CC < 0 AND p.CC_ipo > 0 and p.CC_chi < 0 then 0 ' +
                      'when p.CC < 0 AND p.CC_ipo < 0 and p.CC_chi = 0 then 0 ' +
                      'when p.CC > 0 AND p.CC_ipo >= p.CC_chi          then 0 ' +
                      'else 1 ' +
                    'end as [Prevalenza CHI attuale], ' +
                    'p.SC, ' +
                    '''==>'' as [Recuperi Caricati], ' +
                    '0 as Recuperi, ' +
                    '0 as [Recuperi Fatturabili], ' +
                    '0 as [Recuperi Non Fatturabili], ' +
                    '''==>'' as [Ultima Delibera Assunta], ' +
                    'ud.[Ultima Delibera], ' +
                    'ud.[Data Ultima Delibera], ' +
                    'ud.[Importo Deliberato], ' +
                    'ud.Recuperi_post_delibera, ' +
                    'ud.Delibera_Adempiuta, ' +
                    'ud.Delibera_transattiva, ' +
                    'case when ndg_gdr is null then ''no'' else ''si'' end as GDR, ' +
                    '0 as NroPraticheGruppo, ' +
                    'gdr.ndg_gdr, ' +
                    'gdr.descrizione_gdr, ' +
                    '''==>'' as UCI, ' +
                    'a.Cluster_Prat_Corr, ' +
                    'case a.CLUSTER_PRAT_corr ' +
                      'when ''b''  then ''1) Impresa - Ipotecario'' ' +
                      'when ''a''  then ''2) Impresa - Chirografario'' ' +
                      'when ''c''  then ''3) Impresa - Concorsuale'' ' +
                      'when ''d1'' then ''4.1) Individui - Mutuo Sofferenza'' ' +
                      'when ''d2'' then ''4.2) Individui - Mutuo Incagliato'' ' +
                      'when ''e''  then ''5) Individui - Consumer'' ' +
                      'else null ' +
                    'end as Desc_Cluster_Prat_Corr, ' +
                    'a.Cluster_Prat_Kpi, ' +
                    'case a.Cluster_Prat_Kpi ' +
                      'when ''b''  then ''1) Impresa - Ipotecario'' ' +
                      'when ''a''  then ''2) Impresa - Chirografario'' ' +
                      'when ''c''  then ''3) Impresa - Concorsuale'' ' +
                      'when ''d1'' then ''4.1) Individui - Mutuo Sofferenza'' ' +
                      'when ''d2'' then ''4.2) Individui - Mutuo Incagliato'' ' +
                      'when ''e''  then ''5) Individui - Consumer'' ' +
                      'else null ' +
                    'end as [Desc_Cluster_Prat_Kpi], ' +
                    'year(a.DATA_VINTAGE) as AnnoVintage, ' +
                    'isnull(a.GBV_PRAT_CONF_KPI, p.[Credito Contrattuale Conf]) as CC_conf_con_KPI, ' +
                    'null as RangeCC_conf_con_KPI, ' +
                    'su.[Codice MPP], ' +
                    'su.[MPP Competente], ' +
                    'su.CodAddettoMPP, ' +
                    'su.[Addetto MPP], ' +
                    '''==>'' as [Ck presenza pratica], ' +
                    '''no'' as [Presenza Famiglia Scissione], ' +
                    '''no'' as [Presenza Famiglia Romeo], ' +
                    '''no'' as [Presenza Famiglia SCCI], ' +
                    'case when rio.num_prat is null then ''no'' else ''si'' end as [Perimetro Rio], ' +
                    'case when ticino.Perimetro is null then ''no'' else ''si'' end as [Perimetro Ticino], ' +
                    '''no'' as [Presenza Famiglia Cause Passive], ' +
                    '''no'' as [Presenza Giudizio Ordinario di Merito] ' +
--                    '''no'' as [Irreperibilit&#224; Debitore Principale] ' +
               'from [S1057].dbo.M_A_Department_pratiche_T as p	 with(nolock) ' +
                    'inner join [S1057].dbo.M_A_Anagrafica_DP_T as p1 with(nolock) ' +
                      'on p1.NUM_PRAT = p.NUM_PRAT ' +
                    'inner join [CORESQL7].dbo.LEGPRATI as p2 with(nolock) ' +
                      'on p2.NUM_PRAT = p.NUM_PRAT ' +
                    'left outer join [S1057].dbo.M_A_PGeS_Presenza_LE_T as ul with(nolock) ' +
                      'on ul.NUM_PRAT = p.NUM_PRAT ' +
                    'left outer join [S1057].dbo.M_A_Individui_T as i with(nolock) ' +
                      'on p.CODRESPINT = i.CODUTENTE ' +
                    'left outer join [CORESQL7].dbo.CLUSTER_PRATICA as a with(nolock) ' +
                      'on p.NUM_PRAT = a.NUM_PRAT ' +
                    'left outer join [S1057].dbo.M_A_Individui_T as i_pe with(nolock) ' +
                      'on p.CODRESPONS = i_pe.CODUTENTE ' +
                    'left outer join [S1057].dbo.M_A_Strutture_Unicredit_T as su with(nolock) ' +
                      'on p.NUM_PRAT = su.NUM_PRAT ' +
                    'left outer join [S1057].dbo.PROGETTO_23_F_03_Ticino_T as ticino with(nolock) ' +
                      'on p.NUM_PRAT = ticino.Num_Prat ' +
                    'left outer join [S1057].dbo.M_A_Ultima_delibera_assunta_T as ud with(nolock) ' +
                      'on p.NUM_PRAT = ud.num_prat ' +
                    'left outer join [S1057].dbo.M_A_Gruppi_Economici_T as gdr with(nolock) ' +
                      'on p.NUM_PRAT = gdr.NUM_PRAT ' +
                    'left outer join [ANALISI].dbo.PROGETTO_23_F_03_v2_2015_fam_728_T as rio with(nolock) ' +
                      'on p.NUM_PRAT = rio.num_prat ' +
                    'left outer join [S1057].dbo.TAB_DP_confronto_cap_prov_T as res with(nolock) ' +
                      'on p.NUM_PRAT = res.NUM_PRAT ' +
                    'left outer join [CORESQL7].dbo.legregio as reg with(nolock) ' +
                      'on reg.provincia = res.BB01_RES_PROVINCIA ' +
                    'left outer join [CORESQL7].dbo.legregio_macro as mreg with(nolock) ' +
                      'on reg.cod_macroregione = mreg.id_macroregione ' +
                    'left outer join [S1057].dbo.M_A_Credito_Conferito_T as c with(nolock) ' +
                      'on p.NUM_PRAT = c.num_prat ' +
              'where p.daarchiviare = 0;';

print len(@v_sql);

он убился искать, какой еще incorrect syntax near...,
потому что смотрел свой запрос на экране в необрезанном виде,
а в переменной лежали первые 8000 символов и все.
---------------------
интересно, какая же разница, собирать в переменную запросом из таблицы
или из констант?
12 июл 16, 10:22    [19398309]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5111
Kapadastra
оказывается в некоторых запросах содержит order by в конце запроса, и поэтому все вместе селекты не отрабатывают, теперь думаю как в в вашем извращении отрубать все что после order by включая order by
чем дальше в лес тем толще партизаны...
делайте как вам выше посоветовали - построчное выполнение с сохранением во временную таблицу
12 июл 16, 10:44    [19398451]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Kapadastra
Member

Откуда:
Сообщений: 29
o-o, Удаляет но только одно вхождение определенного кол-ва символов после order by
12 июл 16, 10:48    [19398473]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
o-o
Guest
переформулирую вопрос.
какая разница, как я собираю в переменную,
из таблицы запросом или все то же, но в явном виде?
в первом случае размер суммы может превысить 8000
без явного преобразования,
во втором нет.
это что, заморочки агрегата?
сбор в переменную из таблицы приравнивается к агрегату?
почему перестает работать вот это:
BOL
When two char, varchar, binary, or varbinary expressions are concatenated,
the length of the resulting expression is the sum of the lengths of the two source expressions or 8,000 characters, whichever is less.

Precision, Scale, and Length (Transact-SQL)
declare @t table (s varchar(5000));
insert into @t 
values (replicate('a', 5000)), (replicate('b', 5000));
declare @s_res varchar(max) = '';

select @s_res += s
from @t;

select len(@s_res);
go

declare @s_res varchar(max) = '';
select @s_res = replicate('a', 5000) + replicate('b', 5000);
select len(@s_res);
go

declare @s_res varchar(max) = '';
select @s_res = cast(replicate('a', 5000) as varchar(max)) + replicate('b', 5000);
select len(@s_res);
go
12 июл 16, 10:59    [19398529]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
o-o,

вынеси в отдельную тему, не мучай человека :)
12 июл 16, 11:00    [19398534]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
o-o
Guest
Kapadastra
o-o, Удаляет но только одно вхождение определенного кол-ва символов после order by

лень несусветная?
declare @t table (s varchar(5000));
insert into @t 
values ('SELECT A,B,K,L FROM DBO.T1 ORDER BY A'), 
       ('SELECT C,D FROM DBO.T2 ORDER BY D,C'),
       ('SELECT T,J,L FROM DBO.TTTT');

select s,
       case CHARINDEX('order ', s) 
            when 0 then s
            else stuff(s, CHARINDEX('order ', s), len(s) - CHARINDEX('order ', s) + 1, '')
       end            
from @t;
12 июл 16, 11:05    [19398563]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
alexeyvg
Подвох в том, что это недокументировано?

Да.

Если копнуть глубже, то результат запроса зависит, от того, как раскроет выражение алгебраизатор. А т.к. алгоритм его работы не документирован, то и использовать такой способ не рекомендуют сами МС.

Например:
--Microsoft SQL Server 2014 - 12.0.2456.0 (X64)
declare @s varchar(max);
declare @t table(a int)
insert @t values(1),(2);
declare @len8000 varchar(8000) = replicate('a',8000);

-- 1
set @s = '';
select @s += @len8000 + @len8000 from @t where a in (1);
select len(@s); -- 8000

-- 2
set @s = '';
select @s += @len8000 + @len8000 from @t where a in (1, 2);
select len(@s); -- 16000

-- 3
set @s = '';
select @s = @s + @len8000 + @len8000 from @t where a in (1,2);
select len(@s); -- 32000

В первом случае результат 8000. Для каждой строки вычисляется @len8000 + @len8000, приводится к varchar(8000) и и присваивается @s.

Во втором случае, две строки, для каждой строки вычисляется @len8000 + @len8000, приводится к varchar(8000) и присоединяется к varchar(max) дважды, в итоге 16000. Т.е. строки обрезаются, но в пределах каждой строки. Общий результат остается varchar(max).

Самое интересно, третий случай, если заменить синтаксис "@s += @" на "@s = @s + @", то результат 32000, так получается, потому, что алгебраизатор раскрыввает выражения по разному.
для одного это:
                ScaOp_Arithmetic x_aopAdd
                    ScaOp_Identifier COL: @s 
                    ScaOp_Arithmetic x_aopAdd
                        ScaOp_Identifier COL: @len8000 
                        ScaOp_Identifier COL: @len8000 

Т.е. сначала вычисляется @len8000 + @len8000, потом приводится к varchar(8000), потом приводится к varchar(max) и складывается с @s. И так для двух строк итого 16000.

Для второго это:
                ScaOp_Arithmetic x_aopAdd
                    ScaOp_Arithmetic x_aopAdd
                       ScaOp_Identifier COL: @s 
                        ScaOp_Identifier COL: @len8000 
                    ScaOp_Identifier COL: @len8000 

Т.е. сначала идет сложение @len8000 + @s, результат приводится к varchar(max), потом прибавляется @len8000 = 16000 и так для двух строк итого 32000.

Если в последнее выражение просто добавить скобки:
-- 4
set @s = '';
select @s = @s + (@len8000 + @len8000) from @t where a in (1,2);
select len(@s);-- 16000

То результат снова 16000, т.к. он будет сначала вычислять @len8000 + @len8000.

Ну а поскольку все это поведение, равно как и выводы таких деревьев операторов, не документировано и может меняться - все это выглядит крайне не надежно, по этому лучше вообще таким способом не пользоваться.
12 июл 16, 11:08    [19398584]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31431
SomewhereSomehow,

Как обычно, блестяще, спасибо за детальный анализ!

Я просто знаю, что эта хрень хрен знает как работает, но так подробно не анализировал :-)
12 июл 16, 11:55    [19398952]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5111
о-о, SomewhereSomehow,

ну дак собственно...
https://msdn.microsoft.com/ru-ru/library/ms190286(v=sql.120).aspx
Результаты выражения
При объединении двух выражений с помощью арифметических, побитовых или строковых операторов тип данных результата определяется используемым оператором.
Сложные выражения, составленные из нескольких символов и операторов, вычисляются в одиночные результаты. Тип данных, параметры сортировки, точность и значение результирующего выражения определяются объединением составляющих выражений (по два за один раз) до тех пор, пока не будет получен конечный результат
далее
https://msdn.microsoft.com/ru-ru/library/ms177561.aspx
+ (объединение строк)
Если результат объединения строк превышает предел в 8 000 байт, то он усекается. Однако усечения не произойдет, если хотя бы одна из сцепляемых строк принадлежит к типу больших значений.
это как с делением 1 на 2 и получением 0
12 июл 16, 13:26    [19399521]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Kapadastra
Member

Откуда:
Сообщений: 29
TaPaK, Почему то в добавлении последней строки удаляет последние два символа
12 июл 16, 13:27    [19399534]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Kapadastra
TaPaK, Почему то в добавлении последней строки удаляет последние два символа


SET @Str = SUBSTRING(@Str,0,LEN(@Str)-8) исправьте под то что написали вы
12 июл 16, 13:30    [19399549]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Дедушка,

Это не противоречит, но и не объясняет разные результаты выражений:
declare @s varchar(max);
declare @len8000 varchar(8000) = replicate('a',8000);

set @s = '';
select @s = @s + @len8000 + @len8000
select len(@s);-- 16000

set @s = '';
select @s += @len8000 + @len8000
select len(@s);-- 8000

Учитывая что в документации:
+= (объединение строк) (Transact-SQL)
Remarks
SET @v1 += 'expression' is equivalent to SET @v1 = @v1 + 'expression'.

А я просто объяснил почему так работает, т. к. это может быть не очевидно.
12 июл 16, 13:49    [19399708]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5111
SomewhereSomehow,

по вашей ссылке: "+= это сначала вычисление, а потом присвоение",
поэтому сначала вычислится @len8000 + @len8000 (с усечением т.к. ни один не max),
а затем только @v1 = @v1 + <вычисленное>

имхо достаточно очевидно
12 июл 16, 13:56    [19399767]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Дедушка
имхо достаточно очевидно
Вы молодец!
12 июл 16, 14:01    [19399801]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
o-o
Guest
Дедушка
о-о, SomewhereSomehow,

ну дак собственно...
https://msdn.microsoft.com/ru-ru/library/ms190286(v=sql.120).aspx
Результаты выражения
При объединении двух выражений с помощью арифметических, побитовых или строковых операторов тип данных результата определяется используемым оператором.
Сложные выражения, составленные из нескольких символов и операторов, вычисляются в одиночные результаты. Тип данных, параметры сортировки, точность и значение результирующего выражения определяются объединением составляющих выражений (по два за один раз) до тех пор, пока не будет получен конечный результат
далее
https://msdn.microsoft.com/ru-ru/library/ms177561.aspx
+ (объединение строк)
Если результат объединения строк превышает предел в 8 000 байт, то он усекается. Однако усечения не произойдет, если хотя бы одна из сцепляемых строк принадлежит к типу больших значений.
это как с делением 1 на 2 и получением 0

ну так разве это объясняет, почему при сборе в переменную из запроса
не усекается до 8000?
какая разница-то, собираю я в запросе из таблицы, или указывая явно каждое слагаемое?
у SomewhereSomehow объяснение есть, у вас, простите, нет
12 июл 16, 14:03    [19399816]     Ответить | Цитировать Сообщить модератору
 Re: Выполнение нескольких запросов хранящихся в полях таблицы  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5111
ну и в догонку по примеру выше
declare @s varchar(max);
declare @len8000 varchar(8000) = replicate('a',8000);

set @s = '';

select @s += @len8000 + @len8000
select len(@s); --8000

select @s += @len8000 + @len8000
select len(@s); --16000

вторая часть показывает именно присвоение когда @s(8000) + вычисленное(8000) уже не усекается
12 июл 16, 14:03    [19399822]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить