Inno Setup Executing a large sql script file during installation - sql-server

I am trying to connect with SQL server and execute a script file while installing the setup. I managed to execute a simple script without GO statement in it.
Question: Is there a way to pass (skip) the GO word and execute the script?
ADOConnection.ConnectionString :=
'Provider=SQLOLEDB;' +
'Data Source=' + ServerEdit.Text + ';' +
'User Id=' + UsernameEdit.Text + ';' +
'Password=' + PasswordEdit.Text + ';' +
'Trusted_Connection=no;';
end;
ADOConnection.Open;
try
ADOCommand := CreateOleObject('ADODB.Command');
ADOCommand.ActiveConnection := ADOConnection;
ScriptPath := ExpandConstant('{tmp}\Script2.sql');
if LoadStringFromFile(ScriptPath, ssquery) then
begin
StringChangeEx(ssquery, 'GO', '', True);
SQLQuery := ssquery
ADOCommand.CommandText := SQLQuery;
ADOCommand.Execute(NULL, NULL, adCmdText or adExecuteNoRecords);
Result := True;
end;
finally
ADOConnection.Close;
end;
The Script2.sql
USE northwind3
GO
/****** Object: StoredProcedure [dbo].[Customers By City] Script Date: 5/25/2016 8:35:45 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Customers By City]
-- Add the parameters for the stored procedure here
(#param1 NVARCHAR(20))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT CustomerID, ContactName, CompanyName, City from Customers as c where c.City=#param1
END
GO
/****** Object: StoredProcedure [dbo].[Customers Count By Region] Script Date: 5/25/2016 8:35:45 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Customers Count By Region]
-- Add the parameters for the stored procedure here
(#param1 NVARCHAR(15))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #count int
SELECT #count = COUNT(*)FROM Customers WHERE Customers.Region = #Param1
RETURN #count
END
NOTE: I am using ADOB for the connection in similar way TLama's answer to How to connect to MS SQL Server using InnoSetup? Except in my case I have to include GO in my script.
Thank you.

You can split the SQL script to separate script files long the go statements and execute them individually in a sequence.
If that's not an option, you have to use API/tool that supports the go statement, i.e. the sqlcmd tool, instead of the ADO.
Or just load the script file and remove the go statements before you execute the script over ADO.
You can use StringChange function.

Related

Microsoft R Server Row by Row Insert

I have a for loop that usually writes to a flat file. This way, if anything breaks, I can start where I left off. I want to convert this process to read and write from a SQL table directly using the new RevoScaleR functions in a SQL Server 2016 stored procedure that executes my R code.
Here is a simple SPROC:
USE [master]
GO
/****** Object: StoredProcedure [dbo].[Rscript_geocodeUSACities_TEST] Script Date: 8/8/2017 11:40:40 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Rscript_geocodeUSACities_TEST]
#usrOutputFilePath varchar(150)
,#usrOutputFileName varchar(150)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #rScript nvarchar(max) = N'
#### USER INPUTS ####
usrOutputFile <- "' + #usrOutputFilePath + #usrOutputFileName + '"
#### ESTABLISH ENVIRONMENT ####
library(data.table)
library(foreach)
library(XML)
library(RCurl)
library(RJSONIO)
##turn off scientific notation
options(scipen=999)
##establish compute context
sqlServerConnString <- "Server=.;Database=External;Trusted_Connection=true"
sqlServerCC <- RxInSqlServer(connectionString=sqlServerConnString)
rxSetComputeContext(sqlServerCC)
print(rxGetComputeContext())
#### GEOCODE ####
print(dfInputData)
rxDataStep(data=dfInputData,outFile=imp.USA_Cities_Map,append="rows")
'
EXECUTE sp_execute_external_script
#language = N'R'
, #script = #rScript
,#input_data_1 =N'select 5 as test_insert'
,#input_data_1_name =N'dfInputData'
;
END
Error ouput:
Error in rxDataStep(data = dfInputData, outFile = imp.USA_Cities_Map, :
object 'imp.USA_Cities_Map' not found
Here you go. You don't need to set the compute context to SQL Server. But you do have to grant login permissions to the local users running the R external processes. They are all added to a local group called SqlRUserGroup, you just need to replace 'dbrownebook' with your server name.
Note that you don't add a database user for the sqlrusergroup, but only add a login. SQL R Services will impersonate the user calling sp_execute_external_script. This is explained in: https://learn.microsoft.com/en-us/sql/advanced-analytics/r/security-considerations-for-the-r-runtime-in-sql-server
use master
go
create login [dbrownebook\sqlrusergroup] from windows
create database [External]
go
use [External]
go
create schema imp
go
create table imp.USA_Cities_Map(test_insert int)
go
/****** Object: StoredProcedure [dbo].[Rscript_geocodeUSACities_TEST] Script Date: 8/8/2017 11:40:40 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE OR ALTER PROCEDURE [dbo].[Rscript_geocodeUSACities_TEST]
#usrOutputFilePath varchar(150)
,#usrOutputFileName varchar(150)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #rScript nvarchar(max) = N'
sqlServerConnString <- "Server=.;Database=External;Trusted_Connection=true"
sqlTable <- RxSqlServerData(table = "imp.USA_Cities_Map", connectionString = sqlServerConnString)
rxDataStep(data=dfInputData,outFile=sqlTable,append="rows")
rxDataStep(data=dfInputData,outFile=sqlTable,append="rows")
rxDataStep(data=dfInputData,outFile=sqlTable,append="rows")
'
EXECUTE sp_execute_external_script
#language = N'R'
, #script = #rScript
,#input_data_1 =N'select 5 as test_insert'
,#input_data_1_name =N'dfInputData'
;
END
GO
exec [Rscript_geocodeUSACities_TEST] '',''
go
select * from imp.USA_Cities_Map

i want select city from cites table and create View in stored Procedure

my stored procedure :
USE [maskanjo.com_travelenterDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[SPSelectCites]
-- Add the parameters for the stored procedure here
#cityName nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
--------------------------Select---------------------
CREATE VIEW CUSTOMERS_VIEW AS
SELECT *
FROM [dbo].[City] where [NameFA] LIKE cityName+'%'
-----------------------------------------------------
END
i want select city from cites table and create View
have error
Error :
Incorrect syntax:'CREATE VIEW' Must be only statement in the batch
The error tells you what the problem is. Try executing the query using the "Exec" command:
declare #sql varchar(max)
set #sql = 'CREATE VIEW CUSTOMERS_VIEW AS SELECT * FROM [dbo].[City]
where [NameFA] LIKE ''' + cityName + '%'''
exec (#sql)

error in multi batch transactional sql script

BEGIN TRAN
SET XACT_ABORT ON
GO
BEGIN TRY
IF OBJECT_ID('dbo.Offer_GetByStudyId', 'p') IS NULL
EXEC ('CREATE PROCEDURE Offer_GetByStudyId as select 1')
END TRY
BEGIN CATCH
THROW;
END CATCH
GO
IF ##error <> 0 and ##trancount > 0 ROLLBACK
IF ##trancount = 0 BEGIN SET NOCOUNT ON; SET NOEXEC ON; END
GO
BEGIN TRY
ALTER PROCEDURE dbo.Offer_GetByStudyId
#StudyId NVARCHAR(MAX) = NULL
AS
BEGIN
DECLARE #Conditions NVARCHAR(MAX) = '';
IF #StudyId IS NOT NULL
BEGIN
SET #Conditions = #Conditions + ' AND o.StudyId = ' + cast(#StudyId as varchar(10))
END
DECLARE #sql NVARCHAR(MAX) = 'SELECT
o.StudyId as StudyId,
o.SampleId as SampleId,
o.Status as Status,
o.Title as Title,
o.Topic as Topic,
o.Description as Description,
o.TestOffer as TestOffer,
T.CPI as CPI
FROM Offers o
LEFT JOIN [dbo].[Terms] T ON (o.[Id] = T.[OfferId]) AND T.Active = 1
WHERE 1 = 1' + #Conditions
EXEC(#sql)
END
END TRY
BEGIN CATCH
THROW;
END CATCH
This is my SQL script, I'm trying to have a multi batch script run as a single transaction, so if one statement fails, all of it will be rolled back. But I here keep getting this error:
Incorrect syntax near BEGIN. expecting EXTERNAL
The begin they are talking about is the one after:
#StudyId NVARCHAR(MAX) = NULL
You need to remove your "GO" statements. These are not part of the TSQL language, they are just statements to tell SSMS/SQLCMD that the batch above should be executed. I'm not clear on the behavior of a transaction split across several GO statements. I would start my removing the "GO"s.
https://msdn.microsoft.com/en-us/library/ms188037.aspx
If you take out the statement ALTER PROCEDURE dbo.Offer_GetByStudyId (Line 22 - 47) from TRY CATCH it will work. i.e delete TRY CATCH (Line 20 and Line 48 - 51)
I've realised I've buried the answer in the below, so I'll bring it up to the top to make it clearer: you cannot wrap any flow control statements around an attempt to create or alter a procedure
A simpler example demonstrates the problem:
create procedure ABC
as
go
select * from sys.objects
alter procedure ABC as
Which produces the message:
Msg 111, Level 15, State 1, Procedure ABC, Line 2
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
This is explicitly documented for CREATE PROCEDURE but for some reason isn't for ALTER PROCEDURE.
The CREATE PROCEDURE statement cannot be combined with other Transact-SQL statements in a single batch.
So the upshot is, you cannot wrap any flow control statements around an attempt to create or alter a procedure.
The reason is actually pretty simple - BEGIN and END aren't required around the body of the stored procedure - and a stored procedure can actually contain multiple "top-level" BEGIN/END pairs:
create procedure ABC as
begin
select * from sys.objects
end
begin
select * from sys.columns
end
is fine - so the only way that SQL Server knows the extent of a stored procedure, when it's being defined, is "from the CREATE/ALTER PROCEDURE until the end of the batch."

Execute SSIS in SSMS

I have a SSIS package which will upload files into tables. I want to execute it as soon as a file has been uploaded and saved to a table. This link showed how to execute it using Stored Procedure. What I did was I created a trigger with the following code:
ALTER TRIGGER [dbo].[tr_ImportFile]
ON [dbo].[ReconMedicalAidFile]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
DECLARE #params VARCHAR(MAX),
#ssisStr VARCHAR(MAX),
#packageName VARCHAR(MAX),
#serverName VARCHAR(MAX)
SET #serverName = 'ServerName'
SET #packageName = 'MyIntegration'
SET #ssisStr = 'dtexec /sq ' + #packageName + ' /ser ' + #serverName
DECLARE #returnCode int
EXEC #returnCode = xp_cmdshell #ssisStr
END
I get the following error Procedure expects parameter 'command_string' of type 'varchar'.
Any help would be appreciated.
Thanks
I think it works when you replace VARCHAR(MAX) with VARCHAR(8000) data types
I went a different route. Still have the trigger but it will execute a SQL Job which contains the SSIS package.
EXEC msdb.dbo.sp_start_job N'JobName' ;

Openrowset with Spaces in source

I am attempting to load an Excel file into SQL Server using the OPENROWSET and I think I have narrowed my issue down to there being spaces in the file name. I am using the following Stored Procedure where the source is dynamically passed in:
USE [MyDB]
GO
/****** Object: StoredProcedure [dbo].[SP_LOAD_EXCEL] Script Date: 08/07/2014 10:22:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--Creates a Store Procedure to take a fully qualified file name and
--load to a temporary database
ALTER PROCEDURE [dbo].[SP_LOAD_EXCEL]
#file nvarchar(max)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sql Nvarchar(max);
SET #Sql = 'INSERT INTO [MyDB].[dbo].[ExcelData]
SELECT *
FROM OPENROWSET (''Microsoft.Ace.OLEDB.12.0''
,''Excel 12.0; Database='+#file +';Extended Properties=''''EXCEL 12.0;HDR=NO;IMEX=1''
,''SELECT * FROM [Sheet1$]'')';
EXEC(#Sql);
END
I am calling the SP with the following and this works:
USE [MyDB]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[SP_LOAD_EXCEL]
#file = N'E:\My_Finalised.xlsx'
SELECT 'Return Value' = #return_value
GO
However if I substitute the filename for E:\Database backups\My_Finalised.xlsx then it doesnt work.
So to summarize:
WORKS: E:\My_Finalised.xlsx
DOESNT WORK: E:\Database backups\My_Finalised.xlsx
How do I get OPENROWSET to accept a source that has spaces in it? Thanks

Resources