Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Типизация метапарсером с повторяющимися алиасами - ошибка. (число прочтений - 1597 )
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Типизация метапарсером с повторяющимися алиасами - ошибка.
10. Декабря 2009 :: 20:04
Печать  
Пишу вот такой простой запрос:
Код
Выбрать все
IF EXISTS (SELECT * from tempdb..sysobjects where id = object_id('tempdb..#TablOstVZ'))
DROP TABLE #TablOstVZ

Declare @PERIODR DateTime
Declare @PERIODN Char(8)
Declare @PERIODK Char(23)
Declare @PERIODE Char(23)
SET @PERIODR = Convert(DateTime,'20091101',112)
SET @PERIODN = '20091201'
SET @PERIODK = '20091201'
SET @PERIODE = '20091209Z'

Declare @Firma Char(9)
SET @Firma = '     1   '

Declare @Val Char(9)
SET @Val = '     1   '

SELECT

	TMP2.Контрагент As [Контрагент],
	TMP2.КредДокумент As [КредДокумент],
	SUM(TMP2.Долг_НачОст) As [Долг_НачОст],
	SUM(TMP2.Долг_Приход) As [Долг_Приход],
	SUM(TMP2.Долг_Расход) As [Долг_Расход],
	SUM(TMP2.Долг_НачОст + TMP2.Долг_Приход - TMP2.Долг_Расход) As [Долг_КонОст]
INTO #TablOstVZ
FROM (
SELECT
	$TabR1.Контрагент AS Контрагент,
	$TabR1.КредДокумент AS КредДокумент,
	$TabR1.Долг AS Долг_НачОст,
	0 AS Долг_Приход,
	0 AS Долг_Расход
FROM
	$РегистрИтоги.ВзаиморасчетыПокупателей AS TabR1 (NOLOCK)
WHERE
	TabR1.PERIOD = @PERIODR

	AND $TabR1.Фирма = @Firma
	AND $TabR1.Валюта = @Val
UNION ALL
SELECT
	$TabR2.Контрагент AS Контрагент,
	$TabR2.КредДокумент AS КредДокумент,
	CASE WHEN TabJ.DATE_TIME_IDDOC < @PERIODK THEN ($TabR2.Долг*((TabR2.DEBKRED+1)%2))- ($TabR2.Долг*TabR2.DEBKRED) ELSE 0 END AS Долг_НачОст,
	CASE WHEN TabJ.DATE_TIME_IDDOC > @PERIODK THEN ($TabR2.Долг*((TabR2.DEBKRED+1)%2)) ELSE 0 END AS Долг_Приход,
	CASE WHEN TabJ.DATE_TIME_IDDOC > @PERIODK THEN ($TabR2.Долг*TabR2.DEBKRED) ELSE 0 END AS Долг_Расход
FROM
	$Регистр.ВзаиморасчетыПокупателей AS TabR2 (NOLOCK)
INNER JOIN _1SJOURN As TabJ (NOLOCK) ON (TabR2.IDDOC = TabJ.IDDOC)
WHERE
	TabJ.DATE_TIME_IDDOC >= @PERIODN
	AND TabJ.DATE_TIME_IDDOC < @PERIODE

	AND $TabR2.Фирма = @Firma
	AND $TabR2.Валюта = @Val

-- По поставщикам
UNION ALL
SELECT
	$TabR1.Контрагент AS Контрагент,
	$TabR1.КредДокумент AS КредДокумент,
	-$TabR1.Долг AS Долг_НачОст,
	0 AS Долг_Приход,
	0 AS Долг_Расход
FROM
	$РегистрИтоги.ВзаиморасчетыПоставщиков AS TabR1 (NOLOCK)
WHERE
	TabR1.PERIOD = @PERIODR

	AND $TabR1.Фирма = @Firma
	AND $TabR1.Валюта = @Val
UNION ALL
SELECT
	$TabR2.Контрагент AS Контрагент,
	$TabR2.КредДокумент AS КредДокумент,
	CASE WHEN TabJ.DATE_TIME_IDDOC < @PERIODK THEN -($TabR2.Долг*((TabR2.DEBKRED+1)%2))- ($TabR2.Долг*TabR2.DEBKRED) ELSE 0 END AS Долг_НачОст,
	CASE WHEN TabJ.DATE_TIME_IDDOC > @PERIODK THEN -($TabR2.Долг*((TabR2.DEBKRED+1)%2)) ELSE 0 END AS Долг_Приход,
	CASE WHEN TabJ.DATE_TIME_IDDOC > @PERIODK THEN -($TabR2.Долг*TabR2.DEBKRED) ELSE 0 END AS Долг_Расход
FROM
	$Регистр.ВзаиморасчетыПоставщиков AS TabR2 (NOLOCK)
INNER JOIN _1SJOURN As TabJ (NOLOCK) ON (TabR2.IDDOC = TabJ.IDDOC)
WHERE
	TabJ.DATE_TIME_IDDOC >= @PERIODN
	AND TabJ.DATE_TIME_IDDOC < @PERIODE

	AND $TabR2.Фирма = @Firma
	AND $TabR2.Валюта = @Val

      ) AS TMP2
GROUP BY

	TMP2.Контрагент,
	TMP2.КредДокумент

HAVING
	(
	(SUM(TMP2.Долг_НачОст) <> 0)
	OR	(SUM(TMP2.Долг_Приход) <> 0)
	OR (SUM(TMP2.Долг_Расход) <> 0)) 


В принципе запрос просто берет обороты и остатки по регистрам
"ВзаиморасчетыПокупателей" и "ВзаиморасчетыПоставщиков", все должно работать прекрасно (если этот запрос выполнить без типизации в QueryAnalis-ере), но вот с типизацией у метапарсера получаются проблемы, а именно вот такой запрос уходит на SQL-сервер (в следующем посте).
  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Типизация метапарсером с повторяющимися алиасами - ошибка.
Ответ #1 - 10. Декабря 2009 :: 20:06
Печать  
Вот такой запрос уходит на SQL после парсера:
Код
Выбрать все
IF EXISTS (SELECT * from tempdb..sysobjects where id = object_id('tempdb..#TablOstVZ'))
DROP TABLE #TablOstVZ

Declare @PERIODR DateTime
Declare @PERIODN Char(8)
Declare @PERIODK Char(23)
Declare @PERIODE Char(23)
SET @PERIODR = Convert(DateTime,'20091101',112)
SET @PERIODN = '20091201'
SET @PERIODK = '20091201'
SET @PERIODE = '20091209Z'

Declare @Firma Char(9)
SET @Firma = '     1   '

Declare @Val Char(9)
SET @Val = '     1   '

SELECT

	TMP2.Контрагент As [Контрагент],
	TMP2.КредДокумент As [КредДокумент],
	SUM(TMP2.Долг_НачОст) As [Долг_НачОст],
	SUM(TMP2.Долг_Приход) As [Долг_Приход],
	SUM(TMP2.Долг_Расход) As [Долг_Расход],
	SUM(TMP2.Долг_НачОст + TMP2.Долг_Приход - TMP2.Долг_Расход) As [Долг_КонОст]
INTO #TablOstVZ
FROM (
SELECT
	TabR1.sp1223 AS Контрагент,
	TabR1.sp1226 AS КредДокумент,
	TabR1.sp1228 AS Долг_НачОст,
	0 AS Долг_Приход,
	0 AS Долг_Расход
FROM
	rg1221 AS TabR1 (NOLOCK)
WHERE
	TabR1.PERIOD = @PERIODR

	AND TabR1.sp1222 = @Firma
	AND TabR1.sp1227 = @Val
UNION ALL
SELECT
	TabR2.sp1223 AS Контрагент,
	TabR2.sp1226 AS КредДокумент,
	CASE WHEN TabJ.DATE_TIME_IDDOC < @PERIODK THEN (TabR2.sp1228*((TabR2.DEBKRED+1)%2))- (TabR2.sp1228*TabR2.DEBKRED) ELSE 0 END AS Долг_НачОст,
	CASE WHEN TabJ.DATE_TIME_IDDOC > @PERIODK THEN (TabR2.sp1228*((TabR2.DEBKRED+1)%2)) ELSE 0 END AS Долг_Приход,
	CASE WHEN TabJ.DATE_TIME_IDDOC > @PERIODK THEN (TabR2.sp1228*TabR2.DEBKRED) ELSE 0 END AS Долг_Расход
FROM
	ra1221 AS TabR2 (NOLOCK)
INNER JOIN _1SJOURN As TabJ (NOLOCK) ON (TabR2.IDDOC = TabJ.IDDOC)
WHERE
	TabJ.DATE_TIME_IDDOC >= @PERIODN
	AND TabJ.DATE_TIME_IDDOC < @PERIODE

	AND TabR2.sp1222 = @Firma
	AND TabR2.sp1227 = @Val

-- По поставщикам
UNION ALL
SELECT
	TabR1.sp1223 AS Контрагент,
	TabR1.sp1226 AS КредДокумент,
	-TabR1.sp1228 AS Долг_НачОст,
	0 AS Долг_Приход,
	0 AS Долг_Расход
FROM
	rg1234 AS TabR1 (NOLOCK)
WHERE
	TabR1.PERIOD = @PERIODR

	AND TabR1.sp1222 = @Firma
	AND TabR1.sp1227 = @Val
UNION ALL
SELECT
	TabR2.sp1223 AS Контрагент,
	TabR2.sp1226 AS КредДокумент,
	CASE WHEN TabJ.DATE_TIME_IDDOC < @PERIODK THEN -(TabR2.sp1228*((TabR2.DEBKRED+1)%2))- (TabR2.sp1228*TabR2.DEBKRED) ELSE 0 END AS Долг_НачОст,
	CASE WHEN TabJ.DATE_TIME_IDDOC > @PERIODK THEN -(TabR2.sp1228*((TabR2.DEBKRED+1)%2)) ELSE 0 END AS Долг_Приход,
	CASE WHEN TabJ.DATE_TIME_IDDOC > @PERIODK THEN -(TabR2.sp1228*TabR2.DEBKRED) ELSE 0 END AS Долг_Расход
FROM
	ra1234 AS TabR2 (NOLOCK)
INNER JOIN _1SJOURN As TabJ (NOLOCK) ON (TabR2.IDDOC = TabJ.IDDOC)
WHERE
	TabJ.DATE_TIME_IDDOC >= @PERIODN
	AND TabJ.DATE_TIME_IDDOC < @PERIODE

	AND TabR2.sp1222 = @Firma
	AND TabR2.sp1227 = @Val

	) AS TMP2
GROUP BY

	TMP2.Контрагент,
	TMP2.КредДокумент

HAVING
	(
	(SUM(TMP2.Долг_НачОст) <> 0)
	OR	(SUM(TMP2.Долг_Приход) <> 0)
	OR (SUM(TMP2.Долг_Расход) <> 0)) 


Как видим таблицы разные а вот поля одинаковые, причем с последнего UNION-а. Ситуацию можно решить изменив алиасы для последних двух запросов, но надо быть осторожным в дальнейшем.
  
Наверх
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Типизация метапарсером с повторяющимися алиасами - ошибка.
Ответ #2 - 11. Декабря 2009 :: 06:37
Печать  
Дык, предлагаешь метапарсеру еще и искать вложенные подзапросы и создавать для них отдельное получение полей? Не слишком ли сложно будет писать подобный парсер?
  
Наверх
ICQ  
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Типизация метапарсером с повторяющимися алиасами - ошибка.
Ответ #3 - 11. Декабря 2009 :: 08:39
Печать  
Salimbek писал(а) 11. Декабря 2009 :: 06:37:
Дык, предлагаешь метапарсеру еще и искать вложенные подзапросы и создавать для них отдельное получение полей? Не слишком ли сложно будет писать подобный парсер?

Может быть, но приведенный запрос очень простой, даже если убрать подзапрос, скорее всего ошибка тоже будет, пробелма не в подзапросе, а в том, что метапарсер не смотри на UNION, а ищет последний FROM с алиасом.
Т.е. ситуация такая, есть запрос:
Код
Выбрать все
Select
T1.Поле
FROM Таблица1 AS T1
UNION ALL
Select
T1.Поле
FROM Таблица2 AS T1
UNION ALL
Select
T1.Поле
FROM Таблица3 AS T1 


В этом случае метапарсер поймет что алиас Т1 относиться к таблице "Таблица3", что конечно же неверно, в каждом своем UNOIN может быть свой алиас и своя таблица (ровно как и в подзапросе). Во всяком случае в самом SQL сервере проблем по этому поводу не возникает (да и не может, потому как идет строгое разграничение подзапросов).
Понятно что это не кричащая проблема, даже и не проблема, а можно отнести к фичам, но в документацию в таком случае надо включить дополнение, что одинаковые алиасы для метапарсера к разным таблицам неприменимы внутри одной инструкции. Это так на будущее, чтобы у людей не возникалы подобные проблемы. Вывод - надо ставить разные алиасы, хотя в стандарте языка SQL такого требования нет.
  
Наверх
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Типизация метапарсером с повторяющимися алиасами - ошибка.
Ответ #4 - 11. Декабря 2009 :: 08:51
Печать  
Как я себе понимаю, никто по факту не парсит полностью весь запрос. Есть определенный шаблон, который наполняется указанным содержимым. А парсить весь текст запроса, выделяя, где же у нас будут подзапросы - по моему ненужное усложнение. То, что задокументировать данную фичу надо - это верно.
Цитата:
Вывод - надо ставить разные алиасы, хотя в стандарте языка SQL такого требования нет.
Причем тут стандарт SQL-я и использование виртуальных таблиц?
З.Ы. Лично от меня Огромное спасибо авторам за данный функционал, существенно упрощающий мне жизнь.
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать