Кто-нибудь имеет представление, почему объект SubSonic 2.2 SubSonic.SqlQuery будет генерировать очень разные sql для одного и того же кода C # при работе с SQL Server 2005 или SQL Server 2008?
У меня есть сайт, который некоторое время работал на SubSonic 2.2 / SQL Server 2005. Я только что обновил БД до mssql 2008 и столкнулся со следующей ошибкой:
SqlException (0x80131904): неверный синтаксис рядом с ключевым словом 'AND'
Я сбросил SqlQuery.ToString () в точке сбоя и заметил следующие различия между выполнением одной и той же кодовой базы в SQL Server 2005 и SQL Server 2008. Вот исходный код:
SubSonic.SqlQuery q = new Select()
.From(Views.VwSearchIndexQuery2Mtx)
.Paged(pageNumber, maximumRows)
.Where(VwSearchIndexQuery2Mtx.Columns.SearchIndexQueryId)
.In(
new Select(SearchIndexQueryGroupMap.Columns.SearchIndexQueryId)
.From(Tables.SearchIndexQueryGroupMap)
.Where(SearchIndexQueryGroupMap.Columns.SearchIndexQueryGroupId)
.IsEqualTo(searchIndexQueryGroupId));
И автоматически сгенерированный sql для SQL Server 2005:
SELECT * FROM
(SELECT ROW_NUMBER() OVER ( ORDER BY CreatedOn DESC ) AS Row
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryId]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryName]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchTerms]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexId]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexName]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[IndustryId]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[IndustryName]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[DaysMonitored]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[Incidents]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[Relevance]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[CreatedOn]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[CreatedBy]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[ModifiedOn]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[ModifiedBy]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[Deleted]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryTypeId]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryTypeName]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[LastUpdatedTime]
FROM [dbo].[Vw_SearchIndexQuery2_Mtx]
WHERE [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryId]
IN (SELECT [dbo].[SearchIndexQueryGroup_Map].[SearchIndexQueryId]
FROM [dbo].[SearchIndexQueryGroup_Map]
WHERE [dbo].[SearchIndexQueryGroup_Map].[SearchIndexQueryGroupId] = @SearchIndexQueryGroupId0 ) )
AS PagedResults WHERE Row >= 1 AND Row <= 20
Автоматически сгенерированный sql для SQL Server 2008:
DECLARE @Page int
DECLARE @PageSize int
SET @Page = 1
SET @PageSize = 20
SET NOCOUNT ON
-- create a temp table to hold order ids
DECLARE @TempTable TABLE (IndexId int identity, _keyID Int)
-- insert the table ids and row numbers into the memory table
INSERT INTO @TempTable ( _keyID )
SELECT [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryId]
FROM [dbo].[Vw_SearchIndexQuery2_Mtx]
WHERE [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryId]
IN (SELECT [dbo].[SearchIndexQueryGroup_Map].[SearchIndexQueryId]
FROM [dbo].[SearchIndexQueryGroup_Map]
WHERE [dbo].[SearchIndexQueryGroup_Map].[SearchIndexQueryGroupId]
= @SearchIndexQueryGroupId0
)
/* it's at this next AND where the error is thrown */
AND [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryId]
IN (SELECT [dbo].[SearchIndexQueryGroup_Map].[SearchIndexQueryId]
FROM [dbo].[SearchIndexQueryGroup_Map]
AND [dbo].[SearchIndexQueryGroup_Map].[SearchIndexQueryGroupId]
= @SearchIndexQueryGroupId0
)
ORDER BY CreatedOn DESC
-- select only those rows belonging to the proper page
SELECT [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryId]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryName]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchTerms]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexId]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexName]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[IndustryId]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[IndustryName]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[DaysMonitored]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[Incidents]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[Relevance]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[CreatedOn]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[CreatedBy]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[ModifiedOn]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[ModifiedBy]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[Deleted]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryTypeId]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryTypeName]
, [dbo].[Vw_SearchIndexQuery2_Mtx].[LastUpdatedTime]
FROM [dbo].[Vw_SearchIndexQuery2_Mtx]
INNER JOIN @TempTable t ON [dbo].[Vw_SearchIndexQuery2_Mtx].[SearchIndexQueryId] = t._keyID
WHERE t.IndexId BETWEEN ((@Page - 1) * @PageSize + 1) AND (@Page * @PageSize)
Я знаю, почему происходит ошибка - sql недействителен из-за того, что я прокомментировал выше. Я просто не могу понять, почему SubSonic генерирует недопустимый SQL после того, как он работал на SQL Server 2008. Вы увидите, что для SQL Server 2008 он использует временную таблицу и, похоже, повторяет подпрограмму WHERE ... IN. запрос. Я подумал, что, возможно, это был уровень совместимости ISO, так как для обновленной БД было установлено значение 100. Поэтому я протестировал, установив его на 90 и 80, и SubSonic генерирует тот же sql, что и в каждом случае. (И, кстати, код, сгенерированный для SQL Server 2005, который использует «select rownumber () over ... as row», прекрасно работает с SQL Server 2008.)
У кого-нибудь есть идеи, почему это происходит и как его отследить?
Большое спасибо,
Терри