Reputation: 2472
I want to do the following. 1) Create a database. 2) Run a script when creates tables, stored procedures, etc. (this script is created by SMS 'generate scripts' option)
I found the following code: http://www.delphipages.com/forum/showthread.php?t=181685 and modified it to this:
try
ADOQuery.ConnectionString := 'Provider=SQLOLEDB.1;Password=' +
edtPassword.Text + ';Persist Security Info=True;User ID=' + edtUser.Text + ';Initial Catalog=master;Data Source=' + edtServerName.Text;
ADOQuery.SQL.Clear; ADOQuery.SQL.Text := 'create DataBase ' + edtWebDBName.Text; ADOQuery.ExecSQL; // should check existance of database ADOWeb.Connected := false; ADOWeb.ConnectionString := 'Provider=SQLOLEDB.1;Password=' +
edtPassword.Text + ';Persist Security Info=True;User ID=' + edtUser.Text + ';Initial Catalog=' + edtWebDBName.Text + ';Data Source=' + edtServerName.Text; ADOWeb.Connected := true;
ADOQuery.Connection := ADOWeb; ADOQuery.SQL.Clear; ADOQuery.SQL.LoadFromFile(edtScriptFileName.Text); ADOQuery.ExecSQL; except
This works up until the point of running the script file. Then it generates an exception: Incorrect Syntax near "GO". If i run the script in SMS on the newly created DB, it is fine. Is this issue due to running more than one SQL command at once (the script is essentially a long list of command/GO statements? How to get around it?
Oh also as a bonus, any thoughts on a quick check to see if the new database actually exists before sending a script to it? (Or is it not necessary since if the create fails it will generate exception?)
Upvotes: 7
Views: 14780
Reputation:
Scripts may contain much more than SQL DDL/DML commands. They can contain variables, small blocks of code, transaction management statement. Usually there are more than one statement, separated by a terminator (a semicolon, the Oracle slash, MSSQL GO, etc, depending on the database you're using and its script syntax). To execute a script properly you have to parse the input file, separate each command, and feed it to the database properly. You can look for library to do that (there are some, IIRC), or yo can try to use the MS SQL command line tool to feed the script via it.
Upvotes: 1
Reputation:
That GO means the end of a batch only for certain Microsoft utilities, it's not a proper T-SQL statement. Try to delete each occurance of GO
in your script and then execute it. That GO
will perform ADOQuery.ExecSQL
for you at the end of your script.
And to your second question; you can use e.g. SQL function DB_ID to check if your DB exists (you have to be on the same server of course). This function returns the database ID; otherwise NULL, so if the following SQL statement returns NULL your database creation failed.
ADOQuery.SQL.Text := 'SELECT DB_ID(' + edtWebDBName.Text + ')';
ADOQuery.Open;
if ADO_Query.Fields[0].IsNull then
ShowMessage('Database creation failed');
Upvotes: 4
Reputation: 136401
Rob the GO
statement is not recognized by ADO, so you must remove from your script before execute.
Now to check if a database exist you can execute a query like this
select COUNT(*) from sys.databases where name='yourdatabasename'
check this very basic sample
assume which you have a script like this
CREATE TABLE Dummy.[dbo].tblUsers(ID INT, UserName VARCHAR(50))
GO
INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (1, 'Jill')
GO
INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (2, 'John')
GO
INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (3, 'Jack')
GO
Now to execute this sentence you can do something like this
const
//in this case the script is inside of a const string but can be loaded from a file as well
Script=
'CREATE TABLE Dummy.[dbo].tblUsers(ID INT, UserName VARCHAR(50)) '+#13#10+
'GO '+#13#10+
'INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (1, ''Jill'') '+#13#10+
'GO '+#13#10+
'INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (2, ''John'') '+#13#10+
'GO '+#13#10+
'INSERT INTO Dummy.[dbo].tblUsers (ID, UserName) VALUES (3, ''Jack'') '+#13#10+
'GO ';
var
DatabaseExist : Boolean;
i : Integer;
begin
try
//check the connection
if not ADOConnection1.Connected then
ADOConnection1.Connected:=True;
//make the query to check if the database called Dummy exist
ADOQuery1.SQL.Add(Format('select COUNT(*) from sys.databases where name=%s',[QuotedStr('Dummy')]));
ADOQuery1.Open;
try
//get the returned value, if is greater than 0 then exist
DatabaseExist:=ADOQuery1.Fields[0].AsInteger>0;
finally
ADOQuery1.Close;
end;
if not DatabaseExist then
begin
//create the database if not exist
ADOQuery1.SQL.Text:=Format('Create Database %s',['Dummy']);
ADOQuery1.ExecSQL;
ADOQuery1.Close;
//load the script, remember can be load from a file too
ADOQuery1.SQL.Text:=Script;
//parse the script to remove the GO statements
for i := ADOQuery1.SQL.Count-1 downto 0 do
if StartsText('GO',ADOQuery1.SQL[i]) then
ADOQuery1.SQL.Delete(i);
//execute the script
ADOQuery1.ExecSQL;
ADOQuery1.Close;
end;
except
on E:Exception do
ShowMessage(E.Message);
end;
end;
Upvotes: 10