Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2006.07.02;
Скачать: [xml.tar.bz2];

Вниз

Скрипт объекта БД посредством SQLDMO.SQLServer   Найти похожие ветки 

 
Ольга   (2006-05-04 17:41) [0]

Скрипты на создание объектов БД получаю с помощью хранимой процедуры, которая вызывает методы SQLDMO.SQLServer. Все было здорово до тех пор, пока не встретился скрипт размером > 8000 (переменная, в которую пишется скрипт @cScript varchar(8000)) Пыталась подставить другой тип - не работает. Может что подскажете, мастера?

DECLARE @oSrv int, @oDB int, @oObj int, @cScript varchar(8000),
       @Server varchar(50),@DataBase varchar(50),@TypeObject varchar(30),@NameObject varchar(50)

SET @Server = "local"
SET @DataBase = "ETALON"
SET @TypeObject = "StoredProcedures"
SET @NameObject = "DeleteFromShema"

EXEC sp_OACreate "SQLDMO.SQLServer", @oSrv output
EXEC sp_OASetProperty @oSrv, "LoginSecure", "TRUE"
EXEC sp_OAMethod @oSrv, "Connect", NULL, @Server
EXEC sp_OAGetProperty @oSrv, "Databases", @oDB output, @DataBase
EXEC sp_OAGetProperty @oDB, @TypeObject, @oObj output, @NameObject
EXEC sp_OAMethod @oObj, "Script",  @cScript output
EXEC sp_OAMethod @oSrv, "Disconnect"
EXEC sp_OADestroy @oSrv
SELECT  @cScript


 
Nikolay M. ©   (2006-05-04 18:23) [1]


> Скрипты на создание объектов БД получаю с помощью хранимой
> процедуры, которая вызывает методы SQLDMO.SQLServer.


Почему бы не написать простенький СОМ-объект, который будет делать все тоже самое, а скрипт класть в файл или в таблицу с NTEXT-полем?


 
sniknik ©   (2006-05-04 21:16) [2]

> varchar(8000)
это максимально возможного размера строка... больше только blob/text

как именно не работает? (ошибка?)


 
Хозяин   (2006-05-05 06:47) [3]

Пыталась подставить другой тип - не работает.

Можно было бы объявить @cScript как ntext, но с локальной переменной так это пройдет.
Но можно сделать такое объявление в параметре этой хранимой процедуры, вот так:

CREATE myProc
 @cScript ntext=NULL
AS


Ну это как вариант...


 
Хозяин   (2006-05-05 06:48) [4]

но с локальной переменной так это не пройдет.


 
Хозяин   (2006-05-05 06:53) [5]

А вообще могу предложить универсальную процедуру "sp_generate_script" из книги Кен Хендерсон "Профессиональное руководство по SQL Server: хранимые процедуры, XML, HTML". Тоже на DMO.


 
Ольга   (2006-05-05 07:13) [6]

Nikolay M. ©

Не хочу формировать скрипт врукопашную - громоздко и по-кустарному. По-моему, лучше, если это делает сам сервер с учетом конкретных особенностей данной БД.

sniknik ©

Когда DECLARE @cScript varchar(8000) ошибка:
ODSOLE Extended Procedure, sp_OAMethod usage:  
ObjPointer int IN, MethodName varchar IN [, @returnval <any> OUT [, additional IN, OUT, or BOTH params]]

Когда DECLARE @cScript text ошибка:
The text, ntext, and image data types are invalid for local variables.


 
Ольга   (2006-05-05 07:17) [7]

Хозяин [5]

Что за процедура sp_generate_script? В Help-е не нашла.


 
Хозяин   (2006-05-05 07:25) [8]

Когда DECLARE @cScript text ошибка:
The text, ntext, and image data types are invalid for local variables.


Попробуйте мне когдато помогло, т.с. выкрутился :)
CREATE PROC myProc
@cScript ntext=NULL
AS


[7] - это самопальная процедура автора книги.
Секунду...сейчас напечатаю выдержку с книги...


 
Хозяин   (2006-05-05 07:34) [9]

[5] + только Ваш скрипт работает через метод "Script", а у него через "SQLDMO.Transfer".

И вот он пишет почему:
"Для использования sp**** необходимо передать ей имя объекта, сценарий которого хотите создать.
...
Если вам приходилось программировать на DMO, возможно, вы удивились тому, что я использовал объект Transfer, а не вызов метода Script для каждого объекта. Причина по которой я так поступил, проста: наличие зависимостей между объектами. Объект Transfer записывает схему объектов в сценарий в порядке их зависимостей. и т.д."


 
Ольга   (2006-05-05 07:47) [10]

[8]
Не помогло. С параметром @cScript ntext=NULL процедура скомпилировалась. Но при выполнении выдала ошибку:
sp_OAMethod Script: ODSOLE Extended Procedure, Error in srv_paramset.

[9]
Это очень интересно. Иерархию зависимостей я строю сама (задачка неожиданно оказалась очень не тривиальной), но не уверена, что отследила все уровни зависимостей. У вас нет небольшого примерчика с использованием объекта Transfer?


 
Хозяин   (2006-05-05 07:56) [11]

У вас нет небольшого примерчика с использованием объекта Transfer?

http://www.xozyain.nm.ru/sp_generate_script.zip


 
Хозяин   (2006-05-05 08:32) [12]

Ольга, не получилось воспроизвести Вашу ошибку, вечерком еще попробую.


 
Ольга   (2006-05-05 10:38) [13]

Разобралась в процедуре sp_generate_script. Она пишет скрипт в файл по назначенному пути. Может по запросу считать информацию из файла.
Создалась процедура у меня с ошибками - в ней есть вызов двух других процедур, которых у меня не оказалось.
1. sp_displayoaerrorinfo - обработка ошибок, я ее создала сама
2. sp_readtextfile - чтение скрипта из файла
Здесь я задумалась, стоит ли связываться с файлами. Сервер не может создать файл на компьютере пользователя, пользователь может не иметь доступа к файловой системе сервера (мой случай), чтобы считать файл с сервера. Можно, конечно, в самой процедуре счтать из файла во временную таблицу... но уж больно кривой путь получается. Надо найти более простое решение.


 
Nikolay M. ©   (2006-05-05 11:17) [14]


> Ольга   (05.05.06 07:13) [6]
>
> Не хочу формировать скрипт врукопашную - громоздко и по-
> кустарному. По-моему, лучше, если это делает сам сервер
> с учетом конкретных особенностей данной БД.


А я и не предлагал делать скрипт вручную, читайте мой ответ внимательнее.


 
Ольга   (2006-05-05 11:33) [15]

[14]
Прочитала внимательнее. Ответа на свой вопрос не нашла: как в СОМ-объекте будет реализована функция, которая генерит скрипт объектов? Конкретнее,  как сгенерированный скрипт (>8000) передать пользователю?


 
Nikolay M. ©   (2006-05-05 11:52) [16]


> ак в СОМ-объекте будет реализована функция, которая генерит
> скрипт объектов?


var
 srv : OleVariant;
begin
 srv := CreateOleObject ("SQLDMO.SQLServer");
 srv.Connect (...);
 // Дальше и так знаете  
end;

Если это должно работать на клиентском компьютере, придется таскать с собой несколько файликов (БОЛ: Installing SQL-DMO).
Если на сервере, то упаковываете код в СОМ-объект, единственную функцию которого будете потом дергать из T-SQL. Передача данных зависит от Ваших конкретных условий, самое тупое - это класть скрипт в табличку с TEXT-полем, а функция будет возвращать ID вставленной записи.


 
Ольга   (2006-05-05 13:32) [17]


> begin
>  srv := CreateOleObject ("SQLDMO.SQLServer");
>  srv.Connect (...);
> // Дальше и так знаете  
> end;

Вот как раз дальше то и не получается. Облом на строке
EXEC sp_OAMethod @oObj, "Script",  @cScript output
т.к. переменной по максимуму @cScript varchar(8000) не хватает для записи в нее скрипта.
Можно воспользоваться методом ScriptTransfer
EXEC sp_OAMethod @object, "ScriptTransfer",NULL, @tfobject, 2, @outputfile
который пишет в файл, но это тоже не устраивает (см.[13])

Хотела уже сдасться и начала делать скрипт врукопашную, но к своему великому удивлению в таблице syscomments в поле text нашла только первые n-символов тела процедуры. Или я не там ищу, или заработалась...


 
Nikolay M. ©   (2006-05-05 13:39) [18]


> Вот как раз дальше то и не получается. Облом на строке
> EXEC sp_OAMethod @oObj, "Script",  @cScript output
> т.к. переменной по максимуму @cScript varchar(8000) не хватает
> для записи в нее скрипта.


Покажите код, который не получается. В Дельфи нет типа varchar(8000), а конструкция

EXEC sp_OAMethod @oObj, "Script",  @cScript output

вообще выдаст ошибку компиляции.


> в таблице syscomments в поле text нашла только первые n-
> символов тела процедуры. Или я не там ищу, или заработалась.


Одно из двух. Если скрипт не помещается в varchar (8000), то он тем более не поместится в nvarchar (4000) (тип поля syscomments.text).


 
Ольга   (2006-05-05 15:46) [19]


> В Дельфи нет типа varchar(8000)

О  Дельфи вообще речи не было. Я пока работаю на сервере БД. В каком виде будет клиентская часть пока не решила (дельфовое приложение, или только DLL, возможно СОМ).

> а конструкция  ...  вообще выдаст ошибку компиляции.

Если в Query записать только эту строку, то конечно. Нужно выполнить весь блок из [0], начиная с создания объекта.


 
Nikolay M. ©   (2006-05-05 16:03) [20]


> Ольга   (05.05.06 15:46) [19]
> О  Дельфи вообще речи не было.


Опять ссылаюсь на [1]. Я не предлагал создавать СОМ-объект именно в Дельфи, делайте на чем нравится.


> > а конструкция  ...  вообще выдаст ошибку компиляции.
>
> Если в Query записать только эту строку, то конечно.


Если в Query записать "только эту строку", то ошибки компиляции не будет. Но опять же, я не предлагал это делать! Как можно так понять код на Дельфи, в котором нет ни слова о Query и его использование даже не предполагается?

var
srv : OleVariant;
begin
srv := CreateOleObject ("SQLDMO.SQLServer");
srv.Connect (...);
// Дальше и так знаете  
end;


Такое ощущение, что Вы в упор не хотите меня понимать, а зациклились на своем T-SQL-ном скрипте. С SQL-DMO, как и с любым другим СОМ-объектом, можно работать не только из T-SQL.


 
Ольга   (2006-05-05 16:12) [21]

То, что зациклилась - это верно подмечено. Сейчас уже врубилась, попробую из Дельфи.


 
Nikolay M. ©   (2006-05-05 16:34) [22]


> Сейчас уже врубилась,



> (05.05.06 16:12) [21]


Лучше поздно, чем никогда :)


 
Хозяин   (2006-05-05 17:07) [23]

Согласен.
:)


 
Хозяин   (2006-05-05 17:38) [24]

Кстати скрипт [0] в QA у меня ошибок не выдавал

с @cScript varchar(8000)
если тело скрипта весит меньше 8000 - то все ОК
если больше - то выдает NULL

[8] - тоже выдает NULL, но это понятно.


 
Ольга   (2006-05-06 10:13) [25]

Пытаюсь перевести свой код с T-SQL на Дельфи, не получается. В help-e есть примеры использования SQLDMO на VB6 и С, никак не могу угадать синтаксис для Дельфи. Торможу уже на соединении с базой. Черкните хотя еще пару строк - дальше соображу сама. Привожу код с закоментариными своими попытками (чтобы дурь была видна):

procedure TForm1.Button1Click(Sender: TObject);
var srv, db, sp : OleVariant;  scr: string;
begin
try
 srv := CreateOleObject ("SQLDMO.SQLServer");
 srv.LoginSecure:=True;
 srv.Connect("BRSQL");
 //db:=srv.Databases("ETALON");
 //db:= CreateOleObject ("SQLDMO.Database");
 //db.Name:="ETALON";
 //scr:=srv.Databases("ETALON").StoredProcedures("DeleteFromShema").Script;
 Memo2.Text:=scr;
finally
 srv.DisConnect;
end;

end;


 
Nikolay M. ©   (2006-05-06 10:41) [26]

procedure TForm1.Button1Click(Sender: TObject);
var
 srv, db : OleVariant;
begin
 srv := CreateOleObject ("SQLDMO.SQLServer");
 srv.LoginSecure := False;
 srv.Connect("srv", "login", "pass");
 db := srv.Databases.Item ("Northwind");
 ShowMessage (db.StoredProcedures.Item ("Sales by Year", "dbo").Script);
end;


 
Nikolay M. ©   (2006-05-06 10:45) [27]

И если это планируется делать на клиентских компьютерах, не забудьте, что я говорил о переносе SQL-DMO.


 
Ольга   (2006-05-06 12:15) [28]

Спасибо, заработало!

> И если это планируется делать на клиентских компьютерах,
>  не забудьте, что я говорил о переносе SQL-DMO.

Да, клиент будет не такой тонкий, как хотелось бы. Но что поделаешь - за все надо платить. Одно радует - таких клиентов (админов) будет 1-2 на контору. Еще раз спасибо.


 
Nikolay M. ©   (2006-05-06 12:27) [29]


> Да, клиент будет не такой тонкий, как хотелось бы. Но что
> поделаешь - за все надо платить. Одно радует - таких клиентов
> (админов) будет 1-2 на контору.


Админам можно и целиком клиентскую часть SQL Server установить.
Если все-таки решите ставить только SQL-DMO, советую изучить чужой опыт

http://www.sql.ru/forum/actualthread.aspx?tid=45114



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2006.07.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.011 c
15-1149708868
Kolan
2006-06-07 23:34
2006.07.02
Помогите скомпилить проект на C++


1-1148325243
Цукор5
2006-05-22 23:14
2006.07.02
сжатие данных


1-1148476437
alec_sey
2006-05-24 17:13
2006.07.02
Массивы


10-1121179682
Piter
2005-07-12 18:48
2006.07.02
Вызов функций флешки


15-1147255423
Колдун
2006-05-10 14:03
2006.07.02
Написание многопотчной качалки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский