I use the following as an export query and I had to transfer to a new upgraded windows server 2003-2008R2. I also upgraded from SQL 2005 to SQL 2012 and apparently screwed up some permission. The following code is supposed to write to a file that gets picked up by dbmail and emailed. The problem is its not writing the file and I believe permissions to be the problem but am not sure where I went wrong. I known th this works as it worked for years on the other server without a hitch so the problem has to be permissions I am guessing.
The message I get is as follows and occurs because the file is never created:
Executed as user: NT SERVICE\SQLSERVERAGENT. Attachment file D:\Argosy_import_090513_0001.txt is invalid. [SQLSTATE 42000] (Error 22051). The step failed.
Declare #PeriodStart Datetime
Declare #PeriodEnd Datetime
SELECT #PeriodEnd = GetDate()
,#PeriodStart = dateadd(hour,-72,getdate())
;WITH outpQ
AS
(
SELECT 1 AS grpOrd, CAST(null AS VARCHAR(255)) AS posInGrp, 'A' AS Ord, CaseNumberKey, 'A|' + ClientsKey + '|' + CAST(BRTNumber AS VARCHAR(11)) + '|' + IsNull(replace(convert(char(10), CoverDate, 101), '/', ''), '') + '|' + IsNull(replace(convert(char(10), CoverDate, 101), '/', ''), '') + '|' + IsNull(ParcelNumber, '') + '|' + IsNull(AssessedBeg, '') + '|' + IsNull(AssessedDim, '') + '|' + IsNull(AbbrLegal, '') + '|' + IsNull(WaterFrom, '') + '|' + IsNull(WaterTo, '') + '|' + IsNull(Cast(WaterOpen AS VARCHAR(50)), '') + '|' + IsNull(TaxFrom, '') + '|' + IsNull(TaxTo, '') + '|' + IsNull(Cast(TaxOpen AS VARCHAR(50)), '') AS Extract
FROM newCityCollection.dbo.PropertyInformation
WHERE DateFinished BETWEEN #PeriodStart AND #PeriodEnd AND ClientKey = 2
UNION ALL
SELECT 1 As grpOrd, null AS posInGrp, 'A1', A.CaseNumberKey, 'A1|' + '|' + '|' + B.LienNumber + '|' + IsNull(Cast(B.LienAmt AS VARCHAR(50)), '') + '|' + IsNull(replace(LienDate, '/', ''), '') + '|' + IsNull(B.LienReason, '') AS Extract
FROM newCityCollection.dbo.PropertyInformation A
JOIN newCityCollection.dbo.muniLiens B ON B.CaseNumberKey = A.CaseNumberKey
WHERE A.DateFinished BETWEEN #PeriodStart AND #PeriodEnd AND ClientKey = 2
UNION ALL
SELECT 2 AS grpOrd, CAST(C.InterestsKey AS VARCHAR(11)) AS posInGrp, 'B', A.CaseNumberKey, 'B|' + '|' + IsNull(C.First, '') + '|' + IsNull(C.Middle, '') + '|' + IsNull(C.Last, '') + '|' + IsNull(C.Alias, '') + '|' + IsNull(C.ComName, '') + '|' + IsNull(C.DocRel, '') + '|' + Cast(C.InterestsKey AS VARCHAR(11)) AS Extract
FROM newCityCollection.dbo.PropertyInformation A
JOIN newCityCollection.dbo.Interests C ON C.CaseNumberKey = A.CaseNumberKey
WHERE A.DateFinished BETWEEN #PeriodStart AND #PeriodEnd AND ClientKey = 2
UNION ALL
SELECT 2 AS grpOrd, CAST(C.InterestsKey AS VARCHAR(11)) AS posInGrp, 'B1', A.CaseNumberKey, 'B1|' + IsNull(FullAdd, '') + '|' + IsNull(D.City, '') + '|' + IsNull(D.State, '') + '|' + IsNull(D.Zip, '') AS Extract
FROM newCityCollection.dbo.PropertyInformation A
JOIN newCityCollection.dbo.Interests C ON C.CaseNumberKey = A.CaseNumberKey
JOIN newCityCollection.dbo.InterestAdd D ON D.CaseNumberKey = A.CaseNumberKey AND D.InterestsKey = C.InterestsKey
WHERE A.DateFinished BETWEEN #PeriodStart AND #PeriodEnd AND ClientKey = 2
UNION ALL
SELECT 2 AS grpOrd, CAST(C.InterestsKey AS VARCHAR(11)) AS posInGrp, 'B2', A.CaseNumberKey, 'B2|' + '|' + IsNull(E.SuitNumber, '') + '|' + Cast(E.BDate AS VARCHAR(11)) + '|' + IsNull(E.Chapter, '') + '|' + IsNull(E.VS, '') AS Extract
FROM newCityCollection.dbo.PropertyInformation A
JOIN newCityCollection.dbo.Interests C ON C.CaseNumberKey = A.CaseNumberKey
JOIN newCityCollection.dbo.Banks E ON E.CaseNumberKey = A.CaseNumberKey AND E.InterestsKey = C.InterestsKey
WHERE A.DateFinished BETWEEN #PeriodStart AND #PeriodEnd AND ClientKey = 2
UNION ALL
SELECT 3 As grpOrd3, null AS posInGrp, 'B3', A.CaseNumberKey, 'B3|' + '|' + F.DocType + '|' + IsNull(Cast(F.DocAmt AS VARCHAR(50)), '') + '|' + IsNull(replace(convert(char(10), DocDate, 101), '/', ''), '') + '|' + IsNull(replace(convert(char(10), RecDate, 101), '/', ''), '') + '|' + IsNull(F.DocID, '') + '|' + IsNull(F.Grantee,'') + '|' + IsNull(F.Grantor,'') + Cast(F.DocIDKey AS VARCHAR(11)) AS Extract
FROM newCityCollection.dbo.PropertyInformation A
JOIN newCityCollection.dbo.Documents F ON F.CaseNumberKey = A.CaseNumberKey
WHERE A.DateFinished BETWEEN #PeriodStart AND #PeriodEnd AND ClientKey = 2
UNION ALL
SELECT 4 AS grpOrd, null AS posInGrp, 'C', A.CaseNumberKey, 'C|' + IsNull(J.CType, '') + '|' + IsNull(J.plaintiffName,'') + '|' + IsNull(J.plaintiffAdd1, '') + '|' + IsNull(J.plaintiffCity, '') + '|' + IsNull(J.plaintiffState, '') + '|' + IsNull(J.plaintiffZip, '') + '|' + '|' + IsNull(J.defendantName, '') + '|' + IsNull(J.defendantAdd1, '') + '|' + IsNull(J.defCity, '') + '|' + IsNull(J.defState, '') + '|' + IsNull(J.defZip, '') + '|' + '|' + IsNull(J.Court, '') + '|' + IsNull(J.CaseID, '') + '|' + IsNull(J.JAmt, '') + '|' + IsNull(replace(convert(VarChar(10), JDate, 101), '/', ''), '') + '|' + IsNull(replace(convert(VARCHAR(10), revivedDate, 101), '/', ''), '') AS Extract
FROM newCityCollection.dbo.PropertyInformation A
JOIN Acme.new_judgment_system.dbo.selected_compiled_clean J ON J.CaseNumber = A.CaseNumberKey
WHERE A.DateFinished BETWEEN #PeriodStart AND #PeriodEnd AND ClientKey = 2 AND J.plaintiffName NOT IN (SELECT Plaintiff FROM newCityCollection.dbo.excluded_Plaintiffs)
)
--Extract data set into a table -- dump table in .txt with current date as part of name then delete that table
SELECT Extract INTO datadump FROM outpQ ORDER BY CaseNumberKey, grpOrd, posInGrp, Ord
DECLARE #FileName varchar(50),
#bcpCommand varchar(2000)
SET #FileName = REPLACE('D:\Argosy_import_'+CONVERT(char(8),GETDATE(),1)+'_0001.txt','/','')
SET #bcpCommand = 'bcp "SELECT Extract FROM datadump" QUERYOUT "'
SET #bcpCommand = #bcpCommand + #FileName + '" -U sa -P ********** -T -c'
EXEC master..xp_cmdshell #bcpCommand
DROP table datadump
EXEC msdb.dbo.sp_send_dbmail
#recipients=N'giner#gmail.com',
#body='Message Body',
#subject ='Import file from My Company',
#profile_name ='Mail',
#file_attachments = #FileName;
Did the attachment size get changed to the default?
See if the attachment exists on the server!
Code below shows current attachment size and then sets max size for DBMail.
-- show current size
exec msdb.dbo.sysmail_help_configure_sp 'MaxFileSize'
-- set the max attachment size to 20000 bytes
exec msdb.dbo.sysmail_configure_sp 'MaxFileSize', '20000';
Also, make sure that the attachment extension is allowed in mail.
-- show prohibited extensions
EXEC msdb.dbo.sysmail_help_configure_sp 'ProhibitedExtensions'
Observed a strange behavior with BCP command:
i. If BCP command is executed from command shell, then the file generated is on the local machine
ii. Else if BCP command is executed on SQL Server Management Studio, the file generated is on the server name mentioned with the command.
Hence, make sure you are providing the proper server name (-S parameter) in BCP command.
Related
I have multiple dimension tables and insert script for all tables. i want to insert 1st row as "UNKNOWN" row. when we deploy all the dimension tables for multiple client the UNKNOWN row also should be inserted so How can i do rather manual insertion ?
INSERT INTO Dimension.table1(Column1, Column2,Column3, Effective)
VALUES ('<Unknown>', '<Unknown>', '<Unknown>',GetDate());
INSERT INTO Dimension.[Table2] (Column_A, Column_B,Column_C,Column_D, Column_E, Effective)
VALUES (0,'<Unknown>',0, '<Unknown>','<Unknown>', GetDate());
INSERT INTO Dimension.[Table3] (ColumnX, ColumnY,ColumnX, Effective)
VALUES ('<Unknown>', '<Unknown>', '<Unknown>',GetDate());
I have to automate this script for multiple client.
There are two ways you can do this.
Create an insert script for every single table. This is easier to program, but requires additional work for every new dimension added.
Create a script that dynamically identifies the dimensions, the key value and the appropriate 'Unknown' value based on data type for each attribute. This can be very complicated to create, but is self maintaining as long as you don't add any new data types.
I expect the best choice will entirely depend on how many dimension tables you have, and how often you add new ones.
UPDATED
For what its worth, here is a stored procedure I wrote a few years ago. I'm sure it could use some updating, and for some reason my system is no longer recognizing the line break characters, but it should get you pretty close.
SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO
ALTER PROCEDURE [dbo].[InsertDimSeedRecords]
/*
-----------------------------------------------------------------------------------------------------------
Object Name: dbo.InsertDimSeedRecords
Project: Enterprise Data Warehouse
Purpose: Used to add seed rows to dimension tables, identified as tables prefixed with
Dim or contained in the dim schema.
Detailed description:
1. Identifies all dimension tables based on the Table and Schema parameters
2. Drops Constraints preventing changes to table data
3. Deletes seed values or Truncates tables based on TruncateData parameter
4. Generates new seed value insert statements
5. Inserts new records into table.
6. Re-create constraints
7. Enable constraints (currently disabled)
Example:
EXEC dbo.InsertDimSeedRecords
#DimTableName = 'All',
#Schema = 'All',
#DisplayResults = 'Y',
#ExecuteActions = 'N'
Parameters:
DimTableName - Accepts the Table Name by itself or qualified with the schema name for backward compatibility.
Values 'DimWorkOrder' and 'dbo.DimWorkOrder' will affect the same table.
'All' can be used to affect all dim tables in the specified schema.
#Schema - The schema name to affect. Ex: 'dim','dbo'; Default is 'dbo'
#TruncateData - If 'Y', truncates the dimension tables prior to reseeding.
If 'N', deletes the seed values (negative SK) from the table and inserts newly generated seed values.
Default is 'N'
#DisplayResults - If 'Y', displays a detailed list of all actions executed/planned, including successful actions.
If 'N', Successful actions are not displayed. Default = 'N'
#DisplayErrors - If 'Y', displays all ations that failed to execute, with error numbers and return codes
If 'N', no error details are returned, a ReturnCode is the only result set.
Use 'N' in automated or scripted tasks
Default is 'N'
#ExecuteActions - If 'N', all the tasks will be generated, but not executed. Use this to check what actions would
be performed without making any changes.
If 'Y', all tasks will be executed.
Default is 'Y' to allow for backward compatibility with previous versions
-----------------------------------------------------------------------------------------------------------
Rev | Date Modified | Developer | Change Summary
-----------------------------------------------------------------------------------------------------------
1 | 2013-11-01 | XXXXXXXX | Created
*/
#DimTableName SYSNAME,
#Schema SYSNAME = 'dbo',
#TruncateData CHAR(1) = 'N',
#DisplayResults CHAR(1) = 'N',
#DisplayErrors CHAR(1) = 'N',
#ExecuteActions CHAR(1) = 'Y'
AS
BEGIN
--/*
--*/
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#ErrorLog') IS NOT NULL
BEGIN
DROP TABLE #ErrorLog;
END
CREATE TABLE #ErrorLog (
TableObject NVARCHAR(256),
StepNum INT,
StepCommand NVARCHAR(MAX),
ErrorMessage NVARCHAR(4000),
ErrorNumber INT,
ErrorSeverity INT,
ErrorState INT,
ErrorLine INT,
ErrorProcedure NVARCHAR(200)
);
DECLARE #TableNameCRSR SYSNAME,
#SchemaNameCRSR SYSNAME;
DECLARE Table_Cursor CURSOR --Retrieve all tables to be affected
FOR
SELECT SCHEMA_NAME(o.schema_id),
o.NAME
FROM sys.objects AS O
WHERE o.type = 'U' --U = User Table
AND (
--All Dim tables from All eligible schemas
(
#Schema = 'All'
AND (
SCHEMA_NAME(o.schema_id) = 'dim'
OR o.NAME LIKE 'Dim%'
)
AND SCHEMA_NAME(o.schema_id) <> 'ref'
)
--tables from a specific schema
OR (
SCHEMA_NAME(o.schema_id) = #Schema
AND (
-- A specific table
o.NAME = #DimTableName
-- All dim tables
OR (
#DimTableName = 'All'
AND (
o.NAME LIKE '%Dim%'
OR #Schema = 'dim'
)
)
)
)
OR (SCHEMA_NAME(o.schema_id) + '.' + o.NAME = #DimTableName) --For legacy Schema Qualified #DimTableName values
)
AND NOT o.NAME IN (
--Add excluded/protected tables here
'MasterPackageControl', 'MasterPackageControl_Archive', 'ETLConfiguration', 'Date', 'Time'
);
OPEN Table_Cursor;
FETCH NEXT
FROM Table_Cursor
INTO #SchemaNameCRSR,
#TableNameCRSR
DECLARE #SQLCommand VARCHAR(MAX) = '',
#ProcOrder CHAR(1);
WHILE ##Fetch_Status = 0
BEGIN
DECLARE Worker_Cursor CURSOR
--Cursor to hold all of the commands in the correct processing order;
--this ensures that data is modified after constraints are dropped and before they are re-created,
--and that no constraint definitions are lost
FOR
WITH SQLConstraints
AS (
SELECT SQLDrop = 'RAISERROR (N''Dropping CONSTRAINT ' + OBJECT_NAME(fkc.constraint_object_id) + ''' , 10, 1) WITH NOWAIT;
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = Object_ID(N''[' + OBJECT_SCHEMA_NAME(fkc.parent_object_id) + '].[' + OBJECT_NAME(fkc.constraint_object_id) + ']'') AND parent_object_id =OBJECT_ID(N''[' + OBJECT_SCHEMA_NAME(fkc.parent_object_id) + '].[' + OBJECT_NAME(fkc.parent_object_id) + ']'') ' + ')
BEGIN
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.parent_object_id)) + ' DROP CONSTRAINT ' + QUOTENAME(OBJECT_NAME(fkc.constraint_object_id)) + '' + CHAR(13) + CHAR(10) + 'END
',
SQLDisable = 'RAISERROR (N''Disabling CONSTRAINT ' + OBJECT_NAME(fkc.constraint_object_id) + ''' , 10, 1) WITH NOWAIT;
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = Object_ID(N''[' + OBJECT_SCHEMA_NAME(fkc.parent_object_id) + '].[' + OBJECT_NAME(fkc.constraint_object_id) + ']'') AND parent_object_id =OBJECT_ID(N''[' + OBJECT_SCHEMA_NAME(fkc.parent_object_id) + '].[' + OBJECT_NAME(fkc.parent_object_id) + ']'') ' + ')
BEGIN
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.parent_object_id)) + ' NOCHECK CONSTRAINT ' + QUOTENAME(OBJECT_NAME(fkc.constraint_object_id)) + '' + CHAR(13) + CHAR(10) + 'END
' --+ ' ON DELETE CASCADE'
,
SQLAdd = 'RAISERROR (N''Creating CONSTRAINT [FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id) --+ '_' + RC.name
+ ']'' , 10, 1) WITH NOWAIT;
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.parent_object_id)) + ' WITH NOCHECK ADD CONSTRAINT [FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id) --+ '_' + RC.name
+ '] FOREIGN KEY(' + QUOTENAME(C.NAME) + ') REFERENCES ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.referenced_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.referenced_object_id)) + '(' + QUOTENAME(RC.NAME) + ')
'
--+ ' ON DELETE CASCADE'
,
LenConstraintName = LEN('FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id)),
SQLEnable = 'RAISERROR (N''Enabling CONSTRAINT [FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id) --+ '_' + RC.name
+ ']'' , 10, 1) WITH NOWAIT;
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fkc.parent_object_id)) + '.' + QUOTENAME(OBJECT_NAME(fkc.parent_object_id)) + ' WITH CHECK CHECK CONSTRAINT [FK_' + OBJECT_NAME(fkc.parent_object_id) + '_' + C.NAME + '_' + OBJECT_SCHEMA_NAME(fkc.referenced_object_id) + OBJECT_NAME(fkc.referenced_object_id) + ']
',
NumRank = ROW_NUMBER() OVER (
ORDER BY OBJECT_SCHEMA_NAME(fkc.parent_object_id),
OBJECT_NAME(fkc.parent_object_id)
),
ReferencedTable = OBJECT_NAME(fkc.referenced_object_id),
ReferencedColumn = RC.NAME
FROM sys.foreign_key_columns AS FKC
INNER JOIN sys.columns AS C
ON fkc.parent_object_id = c.object_id
AND fkc.parent_column_id = c.column_id
INNER JOIN sys.columns AS RC
ON fkc.referenced_object_id = rc.object_id
AND fkc.referenced_column_id = rc.column_id
WHERE OBJECT_SCHEMA_NAME(fkc.referenced_object_id) = #SchemaNameCRSR
AND OBJECT_NAME(fkc.referenced_object_id) = #TableNameCRSR
),
SQLTables
AS (
SELECT SQLTruncate = '
RAISERROR (N''TRUNCATE TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + ''' , 10, 1) WITH NOWAIT;
TRUNCATE TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + '
',
NumRank = ROW_NUMBER() OVER (
ORDER BY TABLE_SCHEMA,
TABLE_NAME
),
*
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_TYPE = 'Base Table'
AND TABLE_SCHEMA = #SchemaNameCRSR
AND TABLE_NAME = #TableNameCRSR
),
SQLInserts
AS (
SELECT DISTINCT SQLInsert = 'RAISERROR (N''Inserting ' + QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME) + ''' , 10, 1) WITH NOWAIT;
' + CASE
WHEN OBJECTPROPERTY(OBJECT_ID(QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME)), 'TableHasIdentity') = 1
THEN 'SET IDENTITY_INSERT ' + QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME) + ' ON
'
ELSE ''
END + '
INSERT INTO ' + QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME) + '
( ' + REPLACE(SUBSTRING((
SELECT ', ' + QUOTENAME(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS AS C2
WHERE c2.TABLE_NAME = c1.Table_name
AND c2.TABLE_SCHEMA = c1.table_schema
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
), 2, 16000) + '
)', ', ', CHAR(13) + SPACE(10) + ', ') + '
VALUES
(
' + REPLACE(SUBSTRING((
SELECT ', ' + CASE
WHEN c2.column_name IN ('ModifiedDate', 'UpdateAuditKey')
THEN 'Null --' + c2.COLUMN_NAME
WHEN C2.COLUMN_NAME IN ('CreatedDate', 'EffectiveDate')
THEN '''' + CONVERT(VARCHAR(20), CURRENT_TIMESTAMP, 120) + ''' --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('InsertAuditKey')
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('CurrentIndicator')
THEN '1 --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('RowStamp')
THEN '''-1'' --' + c2.COLUMN_NAME
WHEN c2.data_type = 'bit'
THEN '1 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%char%'
OR c2.data_type = 'ntext'
THEN CASE
WHEN c2.character_maximum_length > 7
THEN '''Unknown'''
WHEN c2.character_maximum_length > 2
THEN '''Unk'''
ELSE '''U'''
END + ' --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%date%'
THEN '''19000101'' --' + c2.column_name
WHEN c2.data_type LIKE 'tinyint'
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%int%'
THEN '-1 --' + c2.COLUMN_NAME
WHEN c2.data_type IN ('numeric', 'decimal', 'float')
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%binary%'
THEN 'cast(-1 as ' + DATA_TYPE + ISNULL('(' + CAST(Character_Maximum_length AS VARCHAR(5)) + '))', '') + ' --' + c2.COLUMN_NAME
END
FROM INFORMATION_SCHEMA.COLUMNS AS C2
WHERE c2.TABLE_NAME = c1.Table_name
AND c2.TABLE_SCHEMA = c1.table_schema
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
), 2, 16000) + '
),
', ', ', CHAR(13) + SPACE(10) + ', ') + '
(
' + REPLACE(SUBSTRING((
SELECT ', ' + CASE
WHEN c2.column_name IN ('ModifiedDate', 'UpdateAuditKey')
THEN 'Null --' + c2.COLUMN_NAME
WHEN C2.COLUMN_NAME IN ('CreatedDate', 'EffectiveDate')
THEN '''' + CONVERT(VARCHAR(20), CURRENT_TIMESTAMP, 120) + ''' --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('InsertAuditKey')
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('CurrentIndicator')
THEN '1 --' + c2.COLUMN_NAME
WHEN c2.column_name IN ('RowStamp')
THEN '''-2'' --' + c2.COLUMN_NAME
WHEN c2.data_type = 'bit'
THEN '1 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%char%'
OR c2.data_type = 'ntext'
THEN CASE
WHEN c2.character_maximum_length > 13
THEN '''Not Applicable'''
WHEN c2.character_maximum_length > 2
THEN '''N/A'''
ELSE '''N'''
END + ' --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%date%'
THEN '''18991231'' --' + c2.column_name
WHEN c2.data_type LIKE 'tinyint'
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%int%'
THEN '-2 --' + c2.COLUMN_NAME
WHEN c2.data_type IN ('numeric', 'decimal', 'float')
THEN '0 --' + c2.COLUMN_NAME
WHEN c2.data_type LIKE '%binary%'
THEN 'cast(-2 as ' + DATA_TYPE + ISNULL('(' + CAST(Character_Maximum_length AS VARCHAR(5)) + '))', '') + ' --' + c2.COLUMN_NAME
END
FROM INFORMATION_SCHEMA.COLUMNS AS C2
WHERE c2.TABLE_NAME = c1.Table_name
AND c2.TABLE_SCHEMA = c1.table_schema
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
), 2, 16000) + '
)
' + CASE
WHEN OBJECTPROPERTY(OBJECT_ID(QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME)), 'TableHasIdentity') = 1
THEN 'SET IDENTITY_INSERT ' + QUOTENAME(c1.TABLE_SCHEMA) + '.' + QUOTENAME(c1.TABLE_NAME) + ' OFF
'
ELSE ''
END + '
', ', ', CHAR(10) + CHAR(13) + SPACE(10) + ', ')
FROM INFORMATION_SCHEMA.COLUMNS AS C1
INNER JOIN INFORMATION_SCHEMA.TABLES AS T
ON C1.TABLE_CATALOG = T.TABLE_CATALOG
AND C1.TABLE_SCHEMA = T.TABLE_SCHEMA
AND C1.TABLE_NAME = T.TABLE_NAME
WHERE 1 = 1
AND t.TABLE_TYPE <> 'VIEW'
AND t.TABLE_SCHEMA = #SchemaNameCRSR
AND t.TABLE_NAME = #TableNameCRSR
),
SQLCleanKey
AS (
SELECT SQLCommand = 'RAISERROR (N''Delete keys from ' + QUOTENAME(tc.TABLE_SCHEMA) + '.' + QUOTENAME(tc.TABLE_NAME) + ''' , 10, 1) WITH NOWAIT;
DELETE FROM ' + QUOTENAME(TC.TABLE_SCHEMA) + '.' + QUOTENAME(TC.TABLE_NAME) + ' WHERE ' + QUOTENAME(ccu.COLUMN_NAME) + ' < 0'
FROM INFORMATION_SCHEMA.constraint_column_usage AS CCU
INNER JOIN INFORMATION_SCHEMA.table_constraints AS TC
ON CCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA
AND CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
AND CCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
AND tc.TABLE_SCHEMA = #SchemaNameCRSR
AND tc.TABLE_NAME = #TableNameCRSR
),
CommandsUnioned
AS (
SELECT SQLCommand = SQLDrop,
ProcOrder = 1
FROM SQLConstraints
WHERE #TruncateData = 'Y'
UNION ALL
SELECT SQLDisable,
ProcOrder = 2
FROM SQLConstraints
WHERE #TruncateData = 'N'
UNION ALL
SELECT SQLTruncate,
ProcOrder = 3
FROM SQLTables
WHERE #TruncateData = 'Y'
UNION ALL
SELECT SQLCommand,
ProcOrder = 4
FROM SQLCleanKey
WHERE #TruncateData = 'N'
UNION ALL
SELECT SQLInsert,
ProcOrder = 5
FROM SQLInserts
UNION ALL
SELECT SQLAdd,
ProcOrder = 6
FROM SQLConstraints
WHERE #TruncateData = 'Y'
UNION ALL
SELECT sqlenable,
procorder = 7
FROM sqlconstraints
)
SELECT SQLCommand,
ProcOrder
FROM CommandsUnioned
ORDER BY ProcOrder,
SQLCommand;
OPEN Worker_Cursor
FETCH NEXT
FROM Worker_Cursor
INTO #SQLCommand,
#ProcOrder
WHILE ##Fetch_Status = 0
BEGIN
BEGIN TRY
IF #ExecuteActions = 'Y'
BEGIN
EXECUTE (#SQLCommand);
END
INSERT INTO #ErrorLog (
TableObject,
StepNum,
StepCommand,
ErrorMessage,
ErrorNumber,
ErrorSeverity,
ErrorState,
ErrorLine,
ErrorProcedure
)
VALUES (
QUOTENAME(#SchemaNameCRSR) + '.' + QUOTENAME(#TableNameCRSR),
CAST(#ProcOrder AS INT),
#SQLCommand,
ISNULL(ERROR_MESSAGE(), '-'),
ERROR_NUMBER(),
ERROR_SEVERITY(),
ERROR_STATE(),
ERROR_LINE(),
ISNULL(ERROR_PROCEDURE(), '-')
)
END TRY
BEGIN CATCH
INSERT INTO #ErrorLog (
TableObject,
StepNum,
StepCommand,
ErrorMessage,
ErrorNumber,
ErrorSeverity,
ErrorState,
ErrorLine,
ErrorProcedure
)
VALUES (
QUOTENAME(#SchemaNameCRSR) + '.' + QUOTENAME(#TableNameCRSR),
CAST(#ProcOrder AS INT),
#SQLCommand,
ERROR_MESSAGE(),
ERROR_NUMBER(),
ERROR_SEVERITY(),
ERROR_STATE(),
ERROR_LINE(),
ISNULL(ERROR_PROCEDURE(), '-')
)
END CATCH
FETCH NEXT
FROM Worker_Cursor
INTO #SQLCommand,
#ProcOrder
END
CLOSE Worker_Cursor;
DEALLOCATE Worker_Cursor;
FETCH NEXT
FROM Table_Cursor
INTO #SchemaNameCRSR,
#TableNameCRSR
END
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;
DECLARE #ret_code INT;
SELECT #ret_code = MAX(ISNULL(ErrorNumber, 0))
FROM #ErrorLog;
IF #DisplayResults = 'Y'
OR #ret_code <> 0
BEGIN
SELECT TableObject,
StepNum,
ErrorMessage,
ErrorNumber,
ErrorSeverity,
ErrorState,
ErrorLine,
ErrorProcedure,
StepCommand
FROM #ErrorLog
WHERE (
(
#DisplayErrors = 'Y'
AND ErrorNumber IS NOT NULL
)
OR #DisplayResults = 'Y'
)
ORDER BY StepNum,
TableObject,
StepCommand
END
RETURN (#ret_code)
END
GO
I have created a stored procedure that returns a single string of concatenated fields. The issue is that some of these fields may be empty strings resulting in a string much like the below:
, Mendip Road, Farnborough, Hampshire, GU14 9LS
or even
, , Farnborough, Hampshire, GU14 9LS
I really want to strip off any leading commas but I'll only know this once the query has been executed. Is there a way of executing the query, pattern-matching the commas and then removing them before finally returning the modified string?
The query itself is as follows:
SET #SQLQuery = 'SELECT TOP 1 REPLACE((ISNULL(POI,'''') + '', '' + ISNULL(Name,'''') + '', '''
+ ' + ISNULL(Settlement,'''') + '', '' + ISNULL(Cou_Unit,'''') + '', '' + ISNULL(Postcode,'''')),'', , '', '', '')'
+ ' AS ClosestAddress FROM [UKStreetsAndPlaces].[dbo].[OS_Locator] ORDER BY '
+ ' (Longitude ' + #LongitudeOperator + ' ' + CAST(ABS(#Longitude) AS VARCHAR(20)) + ')'
+ ' * (Longitude ' + #LongitudeOperator + ' ' + CAST(ABS(#Longitude) AS VARCHAR(20)) + ')'
+ ' + (Latitude - ' + CAST(#Latitude AS VARCHAR(20)) + ') * (Latitude - ' + CAST(#Latitude AS VARCHAR(20)) + ') ASC'
EXECUTE(#SQLQuery)
Concatenate the comma inside the ISNULL expression as follows:
ISNULL(POI + ', ','')
so your query will look like:
SET #SQLQuery = 'SELECT TOP 1 REPLACE((ISNULL(POI + '', '','''') + ISNULL(Name + '', '','''')'
+ ' + ISNULL(Settlement + '', '','''') + ISNULL(Cou_Unit + '', '','''') + ISNULL(Postcode,'''')),'', , '', '', '')'
+ ' AS ClosestAddress FROM [UKStreetsAndPlaces].[dbo].[OS_Locator] ORDER BY '
+ ' (Longitude ' + #LongitudeOperator + ' ' + CAST(ABS(#Longitude) AS VARCHAR(20)) + ')'
+ ' * (Longitude ' + #LongitudeOperator + ' ' + CAST(ABS(#Longitude) AS VARCHAR(20)) + ')'
+ ' + (Latitude - ' + CAST(#Latitude AS VARCHAR(20)) + ') * (Latitude - ' + CAST(#Latitude AS VARCHAR(20)) + ') ASC'
I don't know if you need dynamic SQL for some other reason, but I think something like this should work (with no Dynamic SQL); if you're really sure you need Dynamic SQL for some other reason, then just refactor this idea into your Dynanmic Statement:
DECLARE #ClosestAddress VARCHAR(1000)
SELECT TOP 1
#ClosestAddress = ISNULL(POI + ', ','')
+ ISNULL(Name + ', ','')
+ ISNULL(Settlement + ', ','')
+ ISNULL(Cou_Unit + ', ', '')
+ ISNULL(Postcode,'')
--AS ClosestAddress
FROM [UKStreetsAndPlaces].[dbo].[OS_Locator] ORDER BY (Longitude = 12.2132) * (Longitude = 12.2132) + (Latitude - 12.2132) * (Latitude - 12.2132) ASC
IF (RIGHT(#ClosestAddress, 2) = ', ')
RETURN SUBSTRING(#ClosestAddress, 0, LEN(#ClosestAddress))
ELSE
RETURN #ClosestAddress
Why this should work: Concatenating NULL + ', ' will result in an empty string. Then we check if the string ends with ', ', and if so we return everything but the last two characters.
You could do something like Replace all Comma with space and then do LTRIM and RTRIM and replace all space with comma.
Create table Data(name varchar(10),lastname varchar(10));
insert into Data values('','Doe');
insert into Data values('Jane','Doe');
insert into Data values('Jane','');
SELECT Replace(Rtrim(Ltrim(Replace(ISNULL(name,'') +',' + ISNULL(lastname,'') + ',',',',' '))),' ',',')
from Data
something like : http://sqlfiddle.com/#!3/6a6c6/1
I've tried to implement some dynamic SQL to create a cursor as an extension of a simple SELECT query. The cursor is used as a way to print the GROUPED values returned from the SELECT as a message in SQL Server Management Studio (kind of like a visual summary of the data) . The purpose of this approach is half task related and half to benefit my understanding of how dynamic SQL can be developed. Code reads:
DECLARE #Focus VARCHAR(10);
SET #Focus = 'Completed'; /* User input event focus {Started, Completed} */
DECLARE #PeriodStartDate DATE, #PeriodEndDate DATE;
SET #PeriodStartDate = '04/01/2014';
SET #PeriodEndDate = GETDATE();
DECLARE #sql VARCHAR(MAX);
SET #sql =
'SELECT ' +
'CASE DATEPART(M, ' + '[Event ' + CASE #Focus
WHEN 'Started' THEN 'Start'
WHEN 'Completed' THEN 'End'
END + ' Date]) ' +
' WHEN 1 THEN ''January'' ' +
' WHEN 2 THEN ''February'' ' +
' WHEN 3 THEN ''March'' ' +
' WHEN 4 THEN ''April'' ' +
' WHEN 5 THEN ''May'' ' +
' WHEN 6 THEN ''June'' ' +
' WHEN 7 THEN ''July'' ' +
' WHEN 8 THEN ''August'' ' +
' WHEN 9 THEN ''September'' ' +
' WHEN 10 THEN ''October'' ' +
' WHEN 11 THEN ''November'' ' +
' WHEN 12 THEN ''December'' ' +
' END AS [Event ' + #Focus + ' Month], ' +
' COUNT([Unique ID]) AS [Number of Events] ' +
' FROM [udf_Events](' + #Focus + ', ' + CAST(#PeriodStartDate AS VARCHAR) + ', ' + CAST(#PeriodEndDate AS VARCHAR) + ') ' +
' GROUP BY ' +
' DATEPART(M, ' + '[Event ' + CASE #Focus
WHEN 'Started' THEN 'Start'
WHEN 'Completed' THEN 'End'
END + ' Date]) ' +
' ORDER BY ' +
' DATEPART(M, ' + '[Event ' + CASE #Focus
WHEN 'Started' THEN 'Start'
WHEN 'Completed' THEN 'End'
END + ' Date]) '
;
DECLARE Results CURSOR
FOR
SELECT
#sql;
The error message I receive:
Msg 16924, Level 16, State 1, Line 71 Cursorfetch: The number of
variables declared in the INTO list must match that of selected
columns.
Through grappling with the problem and trying to execute the query as a SELECT statement (removing the complexity of the cursor) using EXEC(#sql) the error message reads:
Invalid column name 'Completed'.
..Which leads me to believe the problem lies with the CASE expression in the first field selected. udf_Events is an in-line table valued function with three arguments. Amongst others, it has columns [Event Start Date] and [Event End Date] which are the values the cursor is looking to do its work on.
Try this...few ' were missing in your query
DECLARE #Focus VARCHAR(10);
SET #Focus = 'Completed'; /* User input event focus {Started, Completed} */
DECLARE #temp VARCHAR(500);
IF(#Focus = 'Completed')
SET #temp = '[Event End Date]'
ELSE
SET #temp = '[Event Start Date]'
DECLARE #PeriodStartDate DATE, #PeriodEndDate DATE;
SET #PeriodStartDate = '04/01/2014';
SET #PeriodEndDate = GETDATE();
DECLARE #sql VARCHAR(MAX);
SET #sql =
'SELECT ' +
'CASE DATEPART(M, ' + #temp + ')' +
' WHEN 1 THEN ''January'' ' +
' WHEN 2 THEN ''February'' ' +
' WHEN 3 THEN ''March'' ' +
' WHEN 4 THEN ''April'' ' +
' WHEN 5 THEN ''May'' ' +
' WHEN 6 THEN ''June'' ' +
' WHEN 7 THEN ''July'' ' +
' WHEN 8 THEN ''August'' ' +
' WHEN 9 THEN ''September'' ' +
' WHEN 10 THEN ''October'' ' +
' WHEN 11 THEN ''November'' ' +
' WHEN 12 THEN ''December'' ' +
' END AS [Event ' + #Focus + ' Month], ' +
' COUNT([Unique ID]) AS [Number of Events] ' +
' FROM [udf_Events](''' + #Focus + ''', ''' + CAST(#PeriodStartDate AS VARCHAR) + ''', ''' + CAST(#PeriodEndDate AS VARCHAR) + ''') ' +
' GROUP BY ' +
' DATEPART(M, ' + #temp + ')' +
' ORDER BY ' +
' DATEPART(M, ' + #temp + ')';
print #sql
You're not quoting the dates in the call to udf_Events so you end up with
[udf_Events](Completed, 2014-04-01, 2014-09-19)
instead of
[udf_Events](Completed, '2014-04-01', '2014-09-19')
The fix is to change the line
' FROM [udf_Events](' + #Focus + ', ' + CAST(#PeriodStartDate AS VARCHAR) + ', ' + CAST(#PeriodEndDate AS VARCHAR) + ') ' +
to
' FROM [udf_Events](' + #Focus + ', ''' + CAST(#PeriodStartDate AS VARCHAR) + ''', ''' + CAST(#PeriodEndDate AS VARCHAR) + ''') ' +
That said, if the parameters to udf_Events are datetimes then I would consider changing the format to YYYYMMDD as this is unambiguous. To do this you can use CONVERT(char(8), <date>, 112) where <date> is the date to be converted.
i.e:
' FROM [udf_Events](' + #Focus + ', ''' + CONVERT(char(8), #PeriodStartDate, 112) + ''', ''' + CONVERT(char(8), #PeriodEndDate, 112) + ''') ' +
I am using a dynamic stored procedure
if #ReportType = 'Daily Batch'
begin
set #SelectionList= 'select ''' + #tag0 + ''' as Tag0 , ''' + #tag1 + ''' as Tag1 , ''' + #tag2 + ''' as Tag2 , ''' + #tag3 + ''' as Tag3 , ''' + #tag4 + ''' as Tag4 , ''' + #tag5 + ''' as Tag5
, ''' + #tag6 + ''' as Tag6 , ''' + #tag7 + ''' as Tag7 , ''' + #tag8 + ''' as Tag8 , ''' + #tag9 + ''' as Tag9 , ''' + #tag10 + ''' as Tag10 , ''' + #tag11 + ''' as Tag11
, ' + #value0 + ' as Value0 , ' + #value1 + ' as Value1, ' + #value2 + ' as Value2 , ' + #value3 + ' as Value3 , ' + #value4 + ' as Value4 , ' + #value5 + ' as Value5
, ' + #value6 + ' as Value6 , ' + #value7 + ' as Value7 , ' + #value8 + ' as Value8 , ' + #value9 + ' as Value9 , ' + #value10 + ' as Value10 , ' + #value11 + ' as Value11
, RefProductWgt1, RefProductWgt2, RefProductWgt3, RefProductWgt4, RefProductWgt5, RefProductWgt6, RefProductWgt7, RefProductWgt8,
RefProductWgt9, RefProductWgt10, ProductCount, PassCount, RejectCount, UnderWgts, OverWgts, DoubleCount, ReportId, StartDate as GroupColumn
FROM BatchMaster
WHERE SUBSTRING(StartDate, 0, charindex('/' , StartDate, 0))='''+ #startdate+''') AND (DeviceId = '''+#devid+''')
end
exec (#SelectionList)
Here #SelectionList data type is nvarchar(3000), I just want to extract data from a DateTime column...
But it is showing this error:
Operand data type varchar is invalid for divide operator.
Here '/' is used as character not divide, because in my column DateStoreLike (dd-mm-yy/HH:MM:SS), and I am trying to extract only date part before '/' symbol
The error you are receiving is because you need to have two single quotes on each side of the slash:
...WHERE SUBSTRING(StartDate, 0, charindex(''/'' , StartDate, 0))='''+ #startdate+''') AND (DeviceId = '''+#devid+''')
For instance, the following two queries will return '5' as the result:
SELECT charindex('/' , 'this/string', 0)
DECLARE #sql VARCHAR (55) = 'SELECT charindex(''/'' , ''this/string'', 0)'
EXEC(#sql)
When you want a single quote to appear within a string, you need to use two single quotes. To demonstrate this, you can run the following:
SELECT '' --This will return an empty string
SELECT '''' --This will return a single quotation mark
Is it possible to write the following cursor to CTE? It takes an extremely long time to run currently.
Here is my code:
if #ReportSource = 'TAB'
BEGIN
DECLARE yr_cursor CURSOR
FOR
SELECT YEAR, RouteNum, RampInfo, BeginMeasure, EndMeasure, OriginalRoute, Description, CountyDesc, Incidents from #RptParms
OPEN yr_cursor;
FETCH NEXT FROM yr_cursor INTO #Year, #RouteNum, #RampInfo, #BeginMeasure, #EndMeasure, #OriginalRoute, #Description, #CountyDesc, #Incidents;
WHILE (##FETCH_STATUS = 0)
BEGIN
SELECT #sql_str_fred = N'SELECT route_number, beg_measure AS MILELOG, AADT_TOTAL AS VMT, end_measure, RCLINK,YEAR
FROM VW_FRED_AADT_HIST
WHERE route_number = '''+ #RouteNum + '''
and YEAR = '''+ #Year + '''
and FIPS_AND_COUNTY Like ' + '''%' + #CountyDesc + '''
and beg_measure BETWEEN '+ cast(#BeginMeasure as varchar(8)) + ' and ' + cast(#EndMeasure as varchar(8)) + ''
SELECT #sql_str_fred = N' SELECT * from OPENQUERY(EDWGEARS, ''' + REPLACE(#sql_str_fred, '''', '''''') + ''')'
INSERT #freddata (ROUTE_NBR ,
MILELOG ,
VMT ,
END_MEASURE ,
RCLINK ,
YEAR )
EXEC sp_ExecuteSQL #sql_str_fred
FETCH NEXT FROM yr_cursor INTO #Year, #RouteNum, #RampInfo, #BeginMeasure, #EndMeasure, #OriginalRoute, #Description, #CountyDesc, #Incidents;
END
CLOSE yr_cursor
DEALLOCATE yr_cursor
END;
Assume #RptParms - is a table with pameter values and is not huge...
Then all parameters may be combined with query like this:
-- The maximum length of the query string in OPENQUERY is 8 KB !!!
declare
#sql varchar(max) = '
;WITH lst AS (
SELECT * FROM (VALUES
--- values ---
) aa(rn,yr,dsc,m1,m2)
) SELECT route_number, beg_measure AS MILELOG, AADT_TOTAL AS VMT, end_measure, RCLINK,YEAR
FROM VW_FRED_AADT_HIST lst
WHERE route_number = lst.rn
and YEAR = lst.yr
and FIPS_AND_COUNTY Like lst.dsc
and beg_measure BETWEEN lst.m1 and lst.m2
'
select #sql = REPLACE(#sql, '--- values ---', '--- values ---,
(' + ISNULL('''' + RouteNum + '''', 'NULL') -- rn: 1234 --> '1234' or --> NULL
+ ',' + ISNULL('''' + YEAR + '''', 'NULL') -- yn: 1234 --> '1234'
+ ',' + ISNULL('''%'
+ replace(replace(replace(replace(Description
, '[', '[[]')
, '%', '[%]')
, '_', '[_]')
, '''', '''''')
+ '''', 'NULL') -- dsc: a_b[c]%d'e --> '%a[_]b[[]c][%]d''e'
+ ',' + ISNULL('''' + cast(BeginMeasure as varchar(8)) + '''', 'NULL') -- m1: 1234 --> '1234'
+ ',' + ISNULL('''' + cast(EndMeasure as varchar(8)) + '''', 'NULL') -- m2: 1234 --> '1234'
+ ')')
from #RptParms
-- print #sql
/*
;WITH lst AS (
SELECT * FROM (VALUES
--- values ---,
('1234','1234','%a[_]b[[]c][%]d''e','1234','1234'),
('222',NULL,'%abcde','1234','1234'),
(NULL,'1234','%a[_]b[[]c][%]d''e','1234','1234')
) aa(rn,yr,dsc,m1,m2)
) SELECT route_number, beg_measure AS MILELOG, AADT_TOTAL AS VMT, end_measure, RCLINK,YEAR
FROM VW_FRED_AADT_HIST, lst
WHERE route_number = lst.rn
and YEAR = lst.yr
and FIPS_AND_COUNTY Like lst.dsc
and beg_measure BETWEEN lst.m1 and lst.m2
*/
INSERT #freddata (ROUTE_NBR, MILELOG, VMT, END_MEASURE, RCLINK, YEAR)
SELECT *
from OPENQUERY(EDWGEARS, #sql)
Once again:
The maximum length of the query string in OPENQUERY is 8 KB !!!