Microsoft R Server Row by Row Insert - sql-server

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

Related

Stored procedure to alter database recovery mode isnt compiling

I am trying to create a stored procedure that would be generic. I am trying to alter a database and set the recovery mode to either simple or full. It would accept database name and mode as parameter.
The SQL query executes in the context of the master database and alters the database specified. I am trying to incorporate it via Execute SQL task in SSIS. I need the stored procedure to reside in the database that is going to perform the operation on. Not sure how that is going to work. USE database keyword is not allowed in the stored procedure...
The original query works fine but I am facing an issue while trying to execute the stored procedure in the database.It says 'RECOVERY' is not a recognized SET option.
Original query:
use master
ALTER DATABASE XYZ
SET RECOVERY FULL
Stored procedure:
USE XYZ
GO
CREATE PROCEDURE DatabaseRecoveryMode
(#mode varchar(10),
#database varchar(50))
AS
BEGIN
ALTER DATABASE #database
SET RECOVERY #mode
END
The ALTER DATABASE documentation shows the recovery model is a keyword, not a variable. You'll need to construct and execute a dynamic SQL statement for this.
CREATE PROCEDURE dbo.DatabaseRecoveryMode
(
#mode nvarchar(11),
#database sysname
)
AS
IF #mode NOT IN(N'SIMPLE', N'BULK_LOGGED', N'FULL')
BEGIN
RAISERROR('Recovery model must be SIMPLE, BULK_LOGGED, OR FULL', 16, 1);
RETURN 1;
END;
DECLARE #SQL nvarchar(MAX) = N'ALTER DATABASE '
+ QUOTENAME(#database)
+ N' SET RECOVERY '+ #mode + N';';
EXECUTE(#SQL);
GO
You need to use dynamic SQL
USE XYZ
GO
Create Procedure DatabaseRecoveryMode
(
#mode varchar(10),
#database varchar(50)
)
AS
begin
DECLARE #SQL NVARCHAR(MAX)
DECLARE #db NVARCHAR(60), #Use NVARCHAR(100)
SET #db = N'master'
SET #Use = N'Use ' + #db
SET #SQL = #Use + N' ALTER DATABASE '+ #database + N' SET RECOVERY ' + #mode ;
--SELECT #SQL
EXEC sys.sp_executesql #SQL ;
end
GO

Unable to create the tSQLtCLR assembly in SQL Server 2017

I recently installed SQL Server 2017 Express and localdb (general availablity). While attempting to install the tSQLt framework I've discovered a new security feature implemented in SQL Server 2017: the "clr strict security" option. This new security feature seems to prevent the creation of the tSQLtCLR assembly.
The SQL error message states:
CREATE or ALTER ASSEMBLY for assembly 'tSQLtCLR' with the SAFE or
EXTERNAL_ACCESS option failed because the 'clr strict security' option
of sp_configure is set to 1. Microsoft recommends that you sign the
assembly with a certificate or asymmetric key that has a corresponding
login with UNSAFE ASSEMBLY permission. Alternatively, you can trust
the assembly using sp_add_trusted_assembly.
I've read Microsoft's technical documentation related to the sp_add_trusted_assembly procedure, but it seems to assume that you were able to successfully create the assembly. How would one code the tSQLtCLR assembly to be listed as "trusted" if you can't get it created in the first place?
SQL Server 2017 introduces a new server-level configuration option named "CLR strict security", and it is enabled by default. This option requires that ALL Assemblies, even SAFE ones, be signed with a certificate or strong name key, and that the Certificate or Asymmetric Key used to do that signing is loaded into [master], and has a Login created from it, and that Login has been granted the UNSAFE ASSEMBLY permission.
Due to SAFE Assemblies now needing to have the signature-based Login in place before being loaded via CREATE ASSEMBLY, it is no longer possible to have an empty, signed Assembly that gets loaded into [master] via CREATE ASSEMBLY ... FROM 0x... WITH PERMISSION_SET = SAFE;.
Now, there are only two ways to create objects usable to set up SQLCLR security from a VARBINARY literal or variable (i.e. not from an external file):
CREATE ASSEMBLY ... FROM 0x...;
CREATE CERTIFICATE ... FROM BINARY = 0x...;
Option #1 is no longer an option, at least not by itself. Option 2 is fine, but was never preferred due Certificates not being fully integrated into the Visual Studio / MSBuild build process.
Fortunately, there are two ways to fix this as discussed in the following two blog posts of mine:
SQLCLR vs. SQL Server 2017, Part 2: “CLR strict security” – Solution 1 — more steps than Part 3, Solution 2 (below), but a good fit for existing projects as it requires almost no changes to the existing solution or even deployment process (and in fact, this is effectively the route that I went for my SQL# project as all it did was add 3 simple steps to the beginning of the installation script)
SQLCLR vs. SQL Server 2017, Part 3: “CLR strict security” – Solution 2
HOWEVER,
that just answers the question of "why" you are in the situation that you are currently in. To fix that situation, assuming that you likely aren't going to update the tSQLt build process to include a Certificate, then you can do a simple one-time fix of:
ALTER DATABASE [master] SET TRUSTWORTHY ON;
EXEC tSQLt.InstallExternalAccessKey;
EXEC master.sys.sp_executesql N'GRANT UNSAFE ASSEMBLY TO [tSQLtExternalAccessKey];';
ALTER DATABASE [master] SET TRUSTWORTHY OFF;
The GRANT UNSAFE ASSEMBLY is there due to the tSQLt.InstallExternalAccessKey Stored Procedure only granting EXTERNAL ACCESS ASSEMBLY to the Login, which used to be fine, but now is not enough.
Of course, you won't be able to load the tSQLt Assemblies until those 4 steps are done, so if the process is to load everything first and that is failing, then you will need to do:
EXEC sp_configure 'clr strict security', 0; RECONFIGURE;
-- Install tSQLt ...
EXEC tSQLt.InstallExternalAccessKey;
EXEC master.sys.sp_executesql N'GRANT UNSAFE ASSEMBLY TO [tSQLtExternalAccessKey];';
EXEC sp_configure 'clr strict security', 1; RECONFIGURE;
I created an issue in the tSQLt GitHub repository with the steps require to incorporate the ideal fix into the source files: https://github.com/tSQLt-org/tSQLt/issues/25
PLEASE NOTE
that none of these possible solutions includes using the new "Trusted Assemblies" feature. That feature should never, ever be used by anyone for any reason (outside of sheer curiosity and testing). The reasons for avoiding it are detailed in several blog posts (currently 3 and more on the way) starting with:
SQLCLR vs. SQL Server 2017, Part 4: “Trusted Assemblies” – The Disappointment
The tSQLt assembly is signed already. For now, you can create the assembly in master, create a certificate from it, drop the assembly again and then take the necessary steps with that certificate.
I'm working on getting the required step to install tSQLt on 2017 automated.
This worked for me:
declare
#hash binary(64)
,#description nvarchar(4000)
select
#hash = HASHBYTES('SHA2_512', af.content)
, #description = a.clr_name
FROM sys.assemblies a
JOIN sys.assembly_files af
ON a.assembly_id = af.assembly_id
WHERE a.is_user_defined = 1
and a.name = 'tSQLtCLR'
EXEC sys.sp_add_trusted_assembly
#hash
,#description
You can use this script on master and then try to run tSQLt framework script query:
USE master
GO
IF OBJECT_ID('tempdb..#Private_GetAssemblyKeyBytes') IS NOT NULL DROP PROCEDURE #Private_GetAssemblyKeyBytes;
GO
CREATE PROCEDURE #Private_GetAssemblyKeyBytes
#AssemblyKeyBytes VARBINARY(MAX) = NULL OUTPUT,
#AssemblyKeyThumbPrint VARBINARY(MAX) = NULL OUTPUT
AS
SELECT #AssemblyKeyBytes =
0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062+
0x652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010300BB91FD5F0000000000000000E00022200B013000000A0000000600000000000042280000002000000040000000000010002000000002000004000000000000+
0x0004000000000000000080000000020000919C0000030040850000100000100000000010000010000000000000100000000000000000000000F02700004F00000000400000A003000000000000000000000000000000000000006000000C000000B82600+
0x001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E746578740000004808000000200000000A0000000200+
0x00000000000000000000000000200000602E72737263000000A00300000040000000040000000C0000000000000000000000000000400000402E72656C6F6300000C00000000600000000200000010000000000000000000000000000040000042000000+
0x000000000000000000000000002428000000000000480000000200050058200000E005000009000000000000000000000000000000382600008000000000000000000000000000000000000000000000000000000000000000000000001E02280F00000A+
0x2A42534A4201000100000000000C00000076322E302E35303732370000000005006C000000A8010000237E0000140200002C02000023537472696E67730000000040040000040000002355530044040000100000002347554944000000540400008C0100+
0x0023426C6F620000000000000002000001471400000900000000FA013300160000010000001000000002000000010000000F0000000E0000000100000001000000000078010100000000000600ED00DE0106005A01DE0106002100AC010F00FE01000006+
0x00490094010600D00094010600B100940106004101940106000D01940106002601940106007900940106003500BF0106001300BF0106009400940106006000940106000D028D010000000001000000000001000100000010002502140241000100010050+
0x20000000008618A601060001000900A60101001100A60106001900A6010A002900A60110003100A60110003900A60110004100A60110004900A60110005100A60110005900A60110006100A60115006900A60110007100A60110007900A60110008100A6+
0x0106002E000B00C5002E001300CE002E001B00ED002E002300F6002E002B000C012E0033000C012E003B000C012E00430012012E004B001D012E0053000C012E005B000C012E00630035012E006B005F012E0073006C0104800000010000000000000001+
0x0000002300140200000200000000000000000000001A000A000000000000000000003C4D6F64756C653E006D73636F726C696200477569644174747269627574650044656275676761626C6541747472696275746500436F6D56697369626C6541747472+
0x696275746500417373656D626C795469746C6541747472696275746500417373656D626C794B65794E616D6541747472696275746500417373656D626C7954726164656D61726B41747472696275746500417373656D626C7946696C6556657273696F6E+
0x41747472696275746500417373656D626C79436F6E66696775726174696F6E41747472696275746500417373656D626C794465736372697074696F6E41747472696275746500436F6D70696C6174696F6E52656C61786174696F6E734174747269627574+
0x6500417373656D626C7950726F6475637441747472696275746500417373656D626C79436F7079726967687441747472696275746500417373656D626C79436F6D70616E794174747269627574650052756E74696D65436F6D7061746962696C69747941+
0x7474726962757465007453514C74417373656D626C794B65792E646C6C0053797374656D0053797374656D2E5265666C656374696F6E002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E496E746572+
0x6F7053657276696365730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F646573004F626A656374007453514C74417373656D626C794B657900656D7074790000000000009C98AF3349A76E+
0x4AA6D306AB985BCF8E00042001010803200001052001011111042001010E042001010208B77A5C561934E08980A00024000004800000940000000602000000240000525341310004000001000100B9AF416AD8DFEDEC08A5652FA257F1242BF4ED60EF5A+
0x7B84A429604D62C919C5663A9C7710A7C5DF9953B69EC89FCE85D71E051140B273F4C9BF890A2BC19C48F22D7B1F1D739F90EEBC5729555F7F8B63ED088BBB083B336F7E38B92D44CFE1C842F09632B85114772FF2122BC638C78D497C4E88C2D656C166+
0x050D6E1EF3940801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301080100020000000000150100107453514C74417373656D626C794B657900000501000000000A0100057453514C74000017010012436F+
0x7079726967687420C2A920203230313900002901002430333536303035622D373166642D346466332D383530322D32376336613630366539653800000C010007312E302E302E3000001D0100187453514C745F4F6666696369616C5369676E696E674B65+
0x7900000000E73936ABF16E67A4775423AE67F541BFE077E40098D90CEE90D33A631CE7C62B60228445A1C9B8A698B13317C65FD100A55706470458F0CE8C8E8CF2F30B457604C6E5F07A6862B1B45AB75E470E9F5D20E7596164413276227809F5BA14FC+
0x8A08DEEB63878D480DAE9D11907249CE1C6F58C9E69E925F071F552DEE436ADA0400000000BB91FD5F00000000020000001C010000D4260000D408000052534453D827CA8B9C7A5A4597EBB065786433D601000000443A5C615C315C735C7453514C7443+
0x4C525C7453514C74417373656D626C794B65795C6F626A5C437275697365436F6E74726F6C5C7453514C74417373656D626C794B65792E706462000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001828000000000000000000003228000000200000000000000000000000000000000000000000000024280000000000000000000000005F+
0x436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF250020001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000+
0x00000000000000000000000100010000003000008000000000000000000000000000000100000000004800000058400000440300000000000000000000440334000000560053005F00560045005200530049004F004E005F0049004E0046004F00000000+
0x00BD04EFFE00000100000001000000000000000100000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073+
0x006C006100740069006F006E00000000000000B004A4020000010053007400720069006E006700460069006C00650049006E0066006F0000008002000001003000300030003000300034006200300000001A000100010043006F006D006D0065006E0074+
0x00730000000000000022000100010043006F006D00700061006E0079004E0061006D00650000000000000000004A0011000100460069006C0065004400650073006300720069007000740069006F006E00000000007400530051004C0074004100730073+
0x0065006D0062006C0079004B006500790000000000300008000100460069006C006500560065007200730069006F006E000000000031002E0030002E0030002E00300000004A001500010049006E007400650072006E0061006C004E0061006D00650000+
0x007400530051004C00740041007300730065006D0062006C0079004B00650079002E0064006C006C00000000004800120001004C006500670061006C0043006F007000790072006900670068007400000043006F00700079007200690067006800740020+
0x00A90020002000320030003100390000002A00010001004C006500670061006C00540072006100640065006D00610072006B00730000000000000000005200150001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000+
0x007400530051004C00740041007300730065006D0062006C0079004B00650079002E0064006C006C00000000002C0006000100500072006F0064007500630074004E0061006D006500000000007400530051004C0074000000340008000100500072006F+
0x006400750063007400560065007200730069006F006E00000031002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000031002E0030002E0030002E0030000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000+
0x000C0000004438000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+
0x000000000000000000
,#AssemblyKeyThumbPrint = 0xE8FFF6F136D7B53E ;
GO
IF OBJECT_ID('tempdb..#Private_EnableCLR') IS NOT NULL DROP PROCEDURE #Private_EnableCLR;
GO
CREATE PROCEDURE #Private_EnableCLR
AS
BEGIN
EXEC master.sys.sp_configure #configname='clr enabled', #configvalue = 1;
RECONFIGURE;
END;
GO
IF OBJECT_ID('tempdb..#Private_GetSQLProductMajorVersion') IS NOT NULL DROP PROCEDURE #Private_GetSQLProductMajorVersion;
GO
CREATE PROCEDURE #Private_GetSQLProductMajorVersion
AS
RETURN CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)),4) AS INT);
GO
DECLARE #Version INT;
EXEC #Version = #Private_GetSQLProductMajorVersion;
PRINT #Version;
GO
IF OBJECT_ID('tempdb..#RemoveAssemblyKey') IS NOT NULL DROP PROCEDURE #RemoveAssemblyKey;
GO
CREATE PROCEDURE #RemoveAssemblyKey
AS
BEGIN
IF(NOT EXISTS(SELECT * FROM sys.fn_my_permissions(NULL,'server') AS FMP WHERE FMP.permission_name = 'CONTROL SERVER'))
BEGIN
RAISERROR('Only principals with CONTROL SERVER permission can execute this procedure.',16,10);
RETURN -1;
END;
DECLARE #master_sys_sp_executesql NVARCHAR(MAX); SET #master_sys_sp_executesql = 'master.sys.sp_executesql';
DECLARE #ProductMajorVersion INT;
EXEC #ProductMajorVersion = #Private_GetSQLProductMajorVersion;
IF SUSER_ID('tSQLtAssemblyKey') IS NOT NULL DROP LOGIN tSQLtAssemblyKey;
EXEC #master_sys_sp_executesql N'IF ASYMKEY_ID(''tSQLtAssemblyKey'') IS NOT NULL DROP ASYMMETRIC KEY tSQLtAssemblyKey;';
EXEC #master_sys_sp_executesql N'IF EXISTS(SELECT * FROM sys.assemblies WHERE name = ''tSQLtAssemblyKey'') DROP ASSEMBLY tSQLtAssemblyKey;';
DECLARE #cmd NVARCHAR(MAX);
IF(#ProductMajorVersion>=14)
BEGIN
DECLARE #TrustedHash NVARCHAR(MAX);
DECLARE #AssemblyKeyBytes VARBINARY(MAX);
EXEC #Private_GetAssemblyKeyBytes #AssemblyKeyBytes = #AssemblyKeyBytes OUT;
SELECT #TrustedHash = CONVERT(NVARCHAR(MAX),HASHBYTES('SHA2_512',#AssemblyKeyBytes),1);
SELECT #cmd =
'IF EXISTS(SELECT 1 FROM sys.trusted_assemblies WHERE hash = ' + #TrustedHash +' AND description = ''tSQLt Ephemeral'')'+
'EXEC sys.sp_drop_trusted_assembly #hash = ' + #TrustedHash + ';';
EXEC master.sys.sp_executesql #cmd;
END;
END;
GO
IF OBJECT_ID('tempdb..#InstallAssemblyKey') IS NOT NULL DROP PROCEDURE #InstallAssemblyKey;
GO
CREATE PROCEDURE #InstallAssemblyKey
AS
BEGIN
IF(NOT EXISTS(SELECT * FROM sys.fn_my_permissions(NULL,'server') AS FMP WHERE FMP.permission_name = 'CONTROL SERVER'))
BEGIN
RAISERROR('Only principals with CONTROL SERVER permission can execute this procedure.',16,10);
RETURN -1;
END;
DECLARE #cmd NVARCHAR(MAX);
DECLARE #cmd2 NVARCHAR(MAX);
DECLARE #master_sys_sp_executesql NVARCHAR(MAX); SET #master_sys_sp_executesql = 'master.sys.sp_executesql';
DECLARE #ProductMajorVersion INT;
EXEC #ProductMajorVersion = #Private_GetSQLProductMajorVersion;
DECLARE #AssemblyKeyBytes VARBINARY(MAX),
#AssemblyKeyThumbPrint VARBINARY(MAX);
EXEC #Private_GetAssemblyKeyBytes #AssemblyKeyBytes OUT, #AssemblyKeyThumbPrint OUT;
SET #cmd = 'IF EXISTS(SELECT * FROM sys.assemblies WHERE name = ''tSQLtAssemblyKey'') DROP ASSEMBLY tSQLtAssemblyKey;';
EXEC #master_sys_sp_executesql #cmd;
SET #cmd2 = 'SELECT #cmd = ''DROP ASSEMBLY ''+QUOTENAME(A.name)+'';'''+
' FROM master.sys.assemblies AS A'+
' WHERE A.clr_name LIKE ''tsqltassemblykey, %'';';
EXEC sys.sp_executesql #cmd2,N'#cmd NVARCHAR(MAX) OUTPUT',#cmd OUT;
EXEC #master_sys_sp_executesql #cmd;
DECLARE #Hash VARBINARY(64) = NULL;
IF(#ProductMajorVersion>=14)
BEGIN
SELECT #Hash = HASHBYTES('SHA2_512',#AssemblyKeyBytes);
SELECT #cmd =
'IF NOT EXISTS (SELECT * FROM sys.trusted_assemblies WHERE [hash] = #Hash)'+
'BEGIN'+
' EXEC sys.sp_add_trusted_assembly #hash = #Hash, #description = N''tSQLt Ephemeral'';'+
'END ELSE BEGIN'+
' SELECT #Hash = NULL FROM sys.trusted_assemblies WHERE [hash] = #Hash AND description <> ''tSQLt Ephemeral'';'+
'END;';
EXEC #master_sys_sp_executesql #cmd, N'#Hash VARBINARY(64) OUTPUT',#Hash OUT;
END;
SELECT #cmd =
'CREATE ASSEMBLY tSQLtAssemblyKey AUTHORIZATION dbo FROM ' +
CONVERT(NVARCHAR(MAX),#AssemblyKeyBytes,1) +
' WITH PERMISSION_SET = SAFE;'
EXEC #master_sys_sp_executesql #cmd;
IF SUSER_ID('tSQLtAssemblyKey') IS NOT NULL DROP LOGIN tSQLtAssemblyKey;
SET #cmd = N'IF ASYMKEY_ID(''tSQLtAssemblyKey'') IS NOT NULL DROP ASYMMETRIC KEY tSQLtAssemblyKey;';
EXEC #master_sys_sp_executesql #cmd;
SET #cmd2 = 'SELECT #cmd = ISNULL(''DROP LOGIN ''+QUOTENAME(SP.name)+'';'','''')+''DROP ASYMMETRIC KEY '' + QUOTENAME(AK.name) + '';'''+
' FROM master.sys.asymmetric_keys AS AK'+
' LEFT JOIN master.sys.server_principals AS SP'+
' ON AK.sid = SP.sid'+
' WHERE AK.thumbprint = #AssemblyKeyThumbPrint;';
EXEC sys.sp_executesql #cmd2,N'#cmd NVARCHAR(MAX) OUTPUT, #AssemblyKeyThumbPrint VARBINARY(MAX)',#cmd OUT, #AssemblyKeyThumbPrint;
EXEC #master_sys_sp_executesql #cmd;
SET #cmd = 'CREATE ASYMMETRIC KEY tSQLtAssemblyKey FROM ASSEMBLY tSQLtAssemblyKey;';
EXEC #master_sys_sp_executesql #cmd;
SET #cmd = 'CREATE LOGIN tSQLtAssemblyKey FROM ASYMMETRIC KEY tSQLtAssemblyKey;';
EXEC #master_sys_sp_executesql #cmd;
SET #cmd = 'DROP ASSEMBLY tSQLtAssemblyKey;';
EXEC #master_sys_sp_executesql #cmd;
IF(#Hash IS NOT NULL)
BEGIN
SELECT #cmd = 'EXEC sys.sp_drop_trusted_assembly #hash = #Hash;';
EXEC #master_sys_sp_executesql #cmd, N'#Hash VARBINARY(64)',#Hash;
END;
IF(#ProductMajorVersion>=14)
BEGIN
SET #cmd = 'GRANT UNSAFE ASSEMBLY TO tSQLtAssemblyKey;';
END
ELSE
BEGIN
SET #cmd = 'GRANT EXTERNAL ACCESS ASSEMBLY TO tSQLtAssemblyKey;';
END;
EXEC #master_sys_sp_executesql #cmd;
END;
GO
IF OBJECT_ID('tempdb..#PrepareServer') IS NOT NULL DROP PROCEDURE #PrepareServer;
GO
CREATE PROCEDURE #PrepareServer
AS
BEGIN
EXEC #Private_EnableCLR;
EXEC #InstallAssemblyKey;
END;
GO
EXEC #PrepareServer;
GO
I was tested this code, on SQL-Server 2016-2017-2019, worked well.

Inno Setup Executing a large sql script file during installation

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.

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)

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