2012-04-22 4 views
2

Примечание: Я бегу под SQL Server 2008 R2 ...Как выполнить длинный динамический запрос (более 4000) символов - снова

Я взял время, чтобы прочитать десятки постов на этом сайте и других сайтах о том, как выполнять динамический SQL, где запрос составляет более 4000 символов. Я попробовал более дюжины предлагаемых решений. Консенсус, как представляется, разбить запрос на переменные 4000-символов, а затем сделать:

EXEC (@SQLQuery1 + @SQLQuery2) 

Это не работает для меня - запрос усечен в конце @ SQLQuery1.

Теперь я видел образцы, как люди «заставляют» длинный запрос, используя REPLICATE пучок пространств и т. Д., Но это реальный запрос, но он становится немного более сложным, чем это.

У меня есть SQL View с именем «Company_A_ItemView».

У меня 10 компаний, которые хотят создать точный вид с разными именами, например. "Company_B_ItemView" "Company_C_ItemView" ..etc.

Если вы предлагаете помощь, пожалуйста, не спрашивайте, почему существует несколько просмотров - просто признайте, что мне нужно сделать это таким образом, хорошо?

Каждая компания имеет свой собственный набор таблиц, а оператор CREATE VIEW ссылается на несколько таблиц по имени. Вот КРАТКАЯ образец, но помните, что общая длина запроса составляет около 6000 символов:

CREATE view [dbo].[Company_A_ItemView] as 
select 
WE.[Item No_], 
WE.[Location Code], 
    LOC.[Bin Number], 
[..more fields, etc.] 
from 
[Company_A_Warehouse_Entry] WE 
left join 
[Company_A_Location] LOC 

... Вы получаете идею

Итак, что я в настоящее время делаю это:

, Вытягивание содержимого инструкции CREATE VIEW в 2 объявленных переменных, например.

Set @SQLQuery1 = (select text 
        from syscomments 
        where ID = 1382894081 and colid = 1) 
Set @SQLQuery2 = (select 
        from syscomments 
        where ID = 1382894081 and colid = 2) 

Обратите внимание, что SQL хранит длинные определения - при создании представления он хранит текст в нескольких записях систем. В моем случае представление разбивается на текстовый фрагмент из 3591 символов в первую запись системы, а остальная часть текста находится во второй записи. Я понятия не имею, почему SQL не использует все 4000 символов в поле syscomment. И утверждение сломано в середине слова.

Обратите внимание, что во всех моих примерах все переменные @SQLQueryxxx объявляются как varchar (max). Я также попробовал объявить их как nvarchar (max) и varchar (8000) и nvarchar (8000) с теми же результатами.

b. Затем я делаю «Поиск и замена» для «Company_A» и заменяю его «Company_B». В приведенном ниже коде переменная «@CompanyID» сначала устанавливается в «Company_B»:

SET @SQLQueryNew1 = @SQLQuery1 
SET @SQLQueryNew1 = REPLACE(@SQLQueryNew1, 'Company_A', @CompanyID) 
SET @SQLQueryNew2 = @SQLQuery2 
SET @SQLQueryNew2 = REPLACE(@SQLQueryNew2, 'Company_A',@CompanyID) 

гр. Затем я попробовать:

EXEC (@SQLQueryNew1 + @SQLQueryNew2) 

Сообщение возвращается указывает, что он пытается выполнить оператор усечен в конце @ SQLQueryNew1, например, 80% (приблизительно) текста запроса.

Я пробовал CAST'ing конечный результат в новый varchar (max) и nvarchar (max) - не повезло Я пробовал CAST'ing исходного запроса новый varchar (max) и nvarchar (max) - не повезло

Я просмотрел результат извлечения оригинального оператора CREATE VIEW, и все в порядке.

Я пробовал различные другие способы получения оригинального CREATE VIEW заявление, например:

Set @SQLQuery1 = (select VIEW_DEFINITION) 
        FROM [MY_DATABASE].[INFORMATION_SCHEMA].[VIEWS] 
        where TABLE_NAME = 'Company_A_ItemView')` 

Это один возвращает только первые 4000 символов на CREATE VIEW

Set @SQLQuery1 = (SELECT (OBJECT_DEFINITION(@ObjectID)) 

Если бы я do a

SELECT LEN(OBJECT_DEFINITION(@ObjectID)) 

оно возвращает правильную длину запроса (например, 5191), но если я lo ok при @ SQLQuery1 или попытаться установить

EXEC(@SQLQuery1), the statement is still truncated. 

c. Есть несколько ссылок, в которых указано, что, поскольку я манипулирую текстом запроса после его получения, результирующие переменные затем усекаются до 4000 символов. Я попробовал CAST'ing результат, как я делаю REPLACE, например.

SET @SQLQueryNew1 = SELECT (CAST(REPLACE(@SQLQueryNew1, 
           'Company_A', 
           @CompanyID) AS varchar(max)) 

Такой же результат.

Я знаю, что существуют другие методы, такие как создание хранимых процедур для создания представлений. Но мнения разрабатываются и несколько «в потоке», поэтому размещение CREATE VIEW внутри хранимой процедуры является громоздким. Моя цель состоит в том, чтобы иметь возможность взглянуть на компанию Company_A и точно ее воспроизвести - несколько раз, за ​​исключением ссылок на имя и имена компании Company_B, названия и имена компаний Company_C и т. Д.

Мне интересно, есть ли кто-нибудь там который сделал этот тип манипулирования длинным оператором SQL CREATE VIEW и попытался его выполнить.

ответ

4

Просто используйте VARCHAR (MAX) или NVARCHAR (MAX). Они отлично работают для EXEC (строка).


FYI,

Обратите внимание, что это как SQL хранит длинные определения - при создании вида, он сохраняет текст в нескольких syscomments записей.

Неправильное использование. Вот как это делается для SQL Server 2000. Начиная с SQL Server 2005 и выше они сохраняются как NVARCHAR (MAX) в одной записи в sys.sql_modules.

syscomments все еще вокруг, но он сохраняется только для чтения исключительно для обеспечения совместимости.


Так что все, что вам нужно сделать, это изменить ваш @ SQLQuery1,2 и т. Д. переменные в одну переменную NVARCHAR (MAX), и вместо этого вытащите код View из столбца [definition] таблицы sys.sql_modules.

Обратите внимание, что вы должны быть осторожны с вашими строковыми манипуляциями, так как есть определенные функции, которые возвратятся к выводу (N) VARCHAR (4000), если все их входные аргументы не являются (N) VARCHAR (MAX). (Извините, я не знаю, какие из них, но REPLACE() может быть одним). На самом деле это может быть причиной того, что вы испытываете такую ​​путаницу в своих тестах.

0

объявлять переменные SQL (@ SQLQuery1 ...), как nvarchar(4000) быть уверены, что каждая часть SQL did't превышает 4000 байт (копировать каждую часть в текстовый файл и проверить размер файла в байтах)

Смежные вопросы