I'm trying to execute my Stored Procedure for some reason it doesn't allow me to - tsql

I've declared the parameters and inserted values in them however it won't allow me to execute my Stored Procedure. Any Help Please will be appreciated. I've tried to execute the Stored procedure in different ways and I still seem to be getting the same error Message.
Procedure has no parameters and arguments were supplied.
USE [ns_lots_of_vlfs]
go
/****** Object: StoredProcedure [dbo].[RestoreBackups] Script Date: 16/02/2023 10:49:09 ******/
SET ansi_nulls ON
go
SET quoted_identifier ON
go
ALTER PROCEDURE [dbo].[Restorebackups] (#DatabaseName VARCHAR(500),
#DatabaseNameCopy VARCHAR(5000),
#RestoreDate DATETIME,
#DiffDate DATETIME = NULL,
#LogDate DATETIME = NULL)
AS
DECLARE #FullBackupSQL NVARCHAR(max),
#DiffBackupSQL NVARCHAR(max),
#LogBackupSQL NVARCHAR(max),
#FullBackupDate DATETIME,
#FullBackupFile NVARCHAR(max),
#DiffBackupFile NVARCHAR(max),
#LogbackupFile NVARCHAR(max),
#FullBackupFileCopy VARCHAR(5000),
#FullBackupFileCopyldf VARCHAR(5000),
#FullBackupFileCopylocationldf VARCHAR(5000)
SET nocount ON
/* Gets the latest full backup to the restore date declared above for the database name declared above.*/
SELECT TOP 1 #FullBackupFile = bmf.physical_device_name,
#FullBackupDate = bs.backup_finish_date
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs
ON bs.media_set_id = bmf.media_set_id
WHERE bs.type = 'D'
AND bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
ORDER BY backup_finish_date DESC
IF NOT EXISTS(SELECT 1
FROM files
WHERE physical_device_name = #FullBackupFile)
INSERT INTO files
(family_sequence_number,
physical_device_name,
mirror,
backup_set_id,
backup_set_uuid)
SELECT TOP 1 family_sequence_number,
physical_device_name,
mirror,
backup_set_id,
backup_set_uuid
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs
ON bs.media_set_id = bmf.media_set_id
WHERE bs.type = 'D'
AND bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
AND NOT EXISTS (SELECT physical_device_name
FROM files
WHERE #FullBackupFile = physical_device_name)
ORDER BY backup_finish_date DESC
/* Gets me the latest full backup to the database name declared above. for the data file path location */
SELECT TOP 1 #FullBackupFileCopy =
Replace(sd.physical_name, #DatabaseName, #DatabaseNameCopy)
FROM sys.master_files sd
WHERE sd.type_desc = 'ROWS'
AND sd.physical_name LIKE '%.mdf'
AND sd.NAME = #DatabaseName
SELECT TOP 1 #FullBackupFileCopylocationldf =
Replace(sl.physical_name, #DatabaseName, #DatabaseNameCopy)
FROM sys.master_files sl
WHERE sl.NAME LIKE '%log'
AND sl.type_desc = 'LOG'
AND sl.NAME LIKE '%' + #DatabaseName + '%'
SELECT TOP 1 #FullBackupFileCopyldf = sl.NAME
FROM sys.master_files sl
WHERE sl.NAME LIKE '%log'
AND sl.type_desc = 'LOG'
AND sl.NAME LIKE '%' + #DatabaseName + '%'
SELECT TOP 1 #DiffDate = bs.backup_finish_date,
#DiffBackupFile = bmf.physical_device_name
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs
ON bs.media_set_id = bmf.media_set_id
WHERE bmf.physical_device_name LIKE '%diff%'
AND bs.backup_finish_date >= #FullBackupDate
AND bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
AND bs.type = 'I'
ORDER BY backup_finish_date DESC
IF NOT EXISTS(SELECT 1
FROM files
WHERE physical_device_name = #DiffBackupFile)
INSERT INTO files
(family_sequence_number,
physical_device_name,
mirror,
backup_set_id,
backup_set_uuid)
SELECT TOP 1 family_sequence_number,
physical_device_name,
mirror,
backup_set_id,
backup_set_uuid
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs
ON bs.media_set_id = bmf.media_set_id
WHERE bs.type = 'I'
AND bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
AND NOT EXISTS (SELECT physical_device_name
FROM files
WHERE #DiffBackupFile = physical_device_name)
ORDER BY backup_finish_date DESC
SET #FullBackupSQL = 'RESTORE DATABASE ' + #DatabaseNameCopy
+ ' FROM DISK = ''' + #FullBackupFile
+ ''' WITH NORECOVERY, MOVE '''
+ #DatabaseName + ''' TO '''
+ #FullBackupFileCopy + ''', MOVE '''
+ #FullBackupFileCopyldf + ''' TO '''
+ #FullBackupFileCopylocationldf
+ ''' , NORECOVERY,NOUNLOAD, STATS = 5'
SET #DiffBackupSQL = 'RESTORE DATABASE ' + #DatabaseNameCopy
+ ' FROM DISK = ''' + #DiffBackupFile
+ ''' WITH FILE = 1, NOUNLOAD, STATS = 5'
IF Object_id('tempdb..#TempTable_log') IS NOT NULL
DROP TABLE #temptable_log
SELECT bmf.family_sequence_number,
bmf.media_family_id,
bmf.media_count,
bmf.logical_device_name,
bmf.physical_device_name,
bmf.device_type,
bmf.physical_block_size,
bmf.mirror,
bs.backup_set_id,
bs.backup_set_uuid,
bs.first_family_number,
bs.first_media_number,
bs.last_family_number,
bs.last_media_number,
bs.catalog_family_number,
bs.catalog_media_number,
bs.position,
bs.expiration_date,
bs.software_vendor_id,
bs.NAME,
bs.description,
bs.user_name,
bs.software_major_version,
bs.software_minor_version,
bs.software_build_version,
bs.time_zone,
bs.mtf_minor_version,
bs.first_lsn,
bs.last_lsn,
bs.checkpoint_lsn,
bs.database_backup_lsn,
bs.database_creation_date,
bs.backup_start_date,
bs.backup_finish_date,
bs.type,
bs.sort_order,
bs.code_page,
bs.compatibility_level,
bs.database_version,
bs.backup_size,
bs.database_name,
bs.server_name,
bs.machine_name,
bs.flags,
bs.unicode_locale,
bs.unicode_compare_style,
bs.collation_name,
bs.is_password_protected,
bs.recovery_model,
bs.has_bulk_logged_data,
bs.is_snapshot,
bs.is_readonly,
bs.is_single_user,
bs.has_backup_checksums,
bs.is_damaged,
bs.begins_log_chain,
bs.has_incomplete_metadata,
bs.is_force_offline,
bs.is_copy_only,
bs.first_recovery_fork_guid,
bs.last_recovery_fork_guid,
bs.fork_point_lsn,
bs.database_guid,
bs.family_guid,
bs.differential_base_lsn,
bs.differential_base_guid,
bs.compressed_backup_size,
bs.key_algorithm,
bs.encryptor_thumbprint,
bs.encryptor_type
INTO #temptable_log
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs
ON bs.media_set_id = bmf.media_set_id
WHERE bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
AND bs.backup_finish_date > #FullBackupDate
AND bs.backup_finish_date > Isnull(#DiffDate, #FullBackupDate)
AND bs.type = 'L'
IF NOT EXISTS(SELECT 1
FROM files
WHERE physical_device_name = #LogbackupFile)
INSERT INTO files
SELECT *
FROM #temptable_log
WHERE physical_device_name NOT IN (SELECT physical_device_name
FROM files)
DECLARE #Counter INT
SET #Counter = 1
WHILE ( #Counter <= (SELECT Count(*)
FROM #temptable_log) )
BEGIN
SELECT TOP 1 #LogbackupFile = physical_device_name,
#LogBackupSQL = #LogbackupFile
FROM #temptable_log
WHERE backup_finish_date > Isnull(#DiffDate, #FullBackupDate)
AND backup_finish_date > #FullBackupDate
AND backup_finish_date <= #RestoreDate
ORDER BY backup_finish_date;
SET #Counter = 1 -- This should start at one --
/*every time you enter the while loop #counter is a new value so 1 then 2 then 3 and so on which retrieves this from the
temp table log.
*/
SET #LogBackupSQL = 'RESTORE LOG ' + #DatabaseNameCopy
+ ' FROM DISK = ''' + #LogbackupFile
+ ''' WITH FILE = 1, NOUNLOAD, STATS = 5,'
DELETE FROM #temptable_log
WHERE physical_device_name = #LogbackupFile;
END
EXEC master..Sp_executesql
#FullBackupSQL,
#DiffBackupSQL,
#LogBackupSQL
I try to execute this
USE [ns_lots_of_vlfs]
GO
DECLARE
#DatabaseName varchar(500) = 'ns_lots_of_vlfs',
#DatabaseNameCopy varchar(5000) = 'ns_lots_of_vlfs_COPY',
#RestoreDate datetime = '2023-02-13 15:45:00.000',
#DiffDate datetime = null,
#LogDate datetime = null
EXECUTE [dbo].[RestoreBackups] #DatabaseName, #DatabaseNameCopy, #RestoreDate
GO
I get this error message
Procedure has no parameters and arguments were supplied.

Related

How to use a While Loop when returning multiple Values using a variable?

I'm trying to return multiple values for my Log Backups, cause when I use a Set variable it only returns one value. I thought about using a while loop as this will loop and return all my logs close to the restore point. However returns back NULL Value. When I use a Set Variable I'm getting the latest Transaction Log file back but I'm not getting the previous logs before that after the latest Full I think this is to do with me using a Set variable as this only outputs one value.
DECLARE #LogbackupFile nvarchar(max),
#DatabaseName varchar(500) = 'ns_lots_of_vlfs',
#DiffDate datetime = null,
#LogDate datetime = null,
#RestoreDate datetime = '2023-01-30 12:00:06.000',
#FullBackupFile nvarchar(max),
#FullBackupDate datetime
SELECT
TOP 1 #FullBackupFile = bmf.physical_device_name,
#FullBackupDate = bs.backup_finish_date
FROM
msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs ON bs.media_set_id = bmf.media_set_id
WHERE
bs.type = 'D'
AND bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
ORDER BY
backup_finish_date DESC IF OBJECT_ID('tempdb..#TempTable_log') IS NOT NULL
DROP
TABLE #TempTable_log
SELECT
bmf.family_sequence_number,
bmf.media_family_id,
bmf.media_count,
bmf.logical_device_name,
bmf.physical_device_name,
bmf.device_type,
bmf.physical_block_size,
bmf.mirror,
bs.backup_set_id,
bs.backup_set_uuid,
bs.first_family_number,
bs.first_media_number,
bs.last_family_number,
bs.last_media_number,
bs.catalog_family_number,
bs.catalog_media_number,
bs.position,
bs.expiration_date,
bs.software_vendor_id,
bs.name,
bs.description,
bs.user_name,
bs.software_major_version,
bs.software_minor_version,
bs.software_build_version,
bs.time_zone,
bs.mtf_minor_version,
bs.first_lsn,
bs.last_lsn,
bs.checkpoint_lsn,
bs.database_backup_lsn,
bs.database_creation_date,
bs.backup_start_date,
bs.backup_finish_date,
bs.type,
bs.sort_order,
bs.code_page,
bs.compatibility_level,
bs.database_version,
bs.backup_size,
bs.database_name,
bs.server_name,
bs.machine_name,
bs.flags,
bs.unicode_locale,
bs.unicode_compare_style,
bs.collation_name,
bs.is_password_protected,
bs.recovery_model,
bs.has_bulk_logged_data,
bs.is_snapshot,
bs.is_readonly,
bs.is_single_user,
bs.has_backup_checksums,
bs.is_damaged,
bs.begins_log_chain,
bs.has_incomplete_metadata,
bs.is_force_offline,
bs.is_copy_only,
bs.first_recovery_fork_guid,
bs.last_recovery_fork_guid,
bs.fork_point_lsn,
bs.database_guid,
bs.family_guid,
bs.differential_base_lsn,
bs.differential_base_guid,
bs.compressed_backup_size,
bs.key_algorithm,
bs.encryptor_thumbprint,
bs.encryptor_type INTO #TempTable_log
FROM
msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs ON bs.media_set_id = bmf.media_set_id
WHERE
bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
AND bs.backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND bs.type = 'L'
AND bmf.physical_device_name LIKE '%Log%'
WHILE (#LogbackupFile IS NOT NULL)
BEGIN
SELECT
#LogBackupFile = bmf.physical_device_name
FROM
#TempTable_log bmf
WHERE
bmf.database_name = #DatabaseName
AND bmf.backup_finish_date <= #RestoreDate
AND bmf.backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND bmf.type = 'L'
AND bmf.physical_device_name LIKE '%Log%' PRINT #LogBackupFile END
SELECT
#LogbackupFile
It's not fully clear to me what you're asking, but it sounds like the problem is you want to do this at the end:
SELECT #LogbackupFile
Where #LogbackupFile was populated in a query like this:
SELECT
#LogBackupFile = bmf.physical_device_name
FROM
#TempTable_log bmf
WHERE
bmf.database_name = #DatabaseName
AND bmf.backup_finish_date <= #RestoreDate
AND bmf.backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND bmf.type = 'L'
AND bmf.physical_device_name LIKE '%Log%'
When what you should do is just select the column and not worry about trying to set a variable at all:
SELECT
bmf.physical_device_name As LogBackupFile
FROM
#TempTable_log bmf
WHERE
bmf.database_name = #DatabaseName
AND bmf.backup_finish_date <= #RestoreDate
AND bmf.backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND bmf.type = 'L'
AND bmf.physical_device_name LIKE '%Log%'
Now your client code can look at the entire result set.
Even better, looking through the code I'm extremely confident this entire thing could be re-written as a single SQL query, with no temp tables or variables at all other than the #DatabaseName, #RestoreDate, and #Diffdate inputs. However, there a few places where the desire to express the code in a procedural paradigm, rather than set-based, is clouding the intent. Also, it is probably easier to grab the #FullBackupDate value in a separate query.
DECLARE #DatabaseName varchar(500) = 'ns_lots_of_vlfs',
#DiffDate datetime = null,
#RestoreDate datetime = '2023-01-30 12:00:06.000',
#FullBackupDate datetime
SELECT TOP 1 #FullBackupDate = bs.backup_finish_date
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs ON bs.media_set_id = bmf.media_set_id
WHERE bs.type = 'D'
AND bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
ORDER BY bs.backup_finish_date DESC
SELECT bmf.physical_device_name As LogBackupFile
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs ON bs.media_set_id = bmf.media_set_id
WHERE bs.database_name = #DatabaseName
AND bs.backup_finish_date <= #RestoreDate
AND bs.backup_finish_date > ISNULL(#DiffDate, #FullBackupDate)
AND bs.type = 'L'
AND bmf.physical_device_name LIKE '%Log%'
And again: this should send the appropriate data back to the client. If you're having trouble retrieving this data perhaps try posting your client code.

Error converting data type varchar to numeric in standard audit trigger

I have been using a standard block of TSQL for auditing of various tables for some time now. However I now have a problem when running the trigger on a new table: "Error converting data type varchar to numeric". This occurs when running the EXEC (#sql) line. I've determined that the code for #sql is:
insert Audit_AppointmentsWS
(Type,
TableName,
PK,
FieldName,
OldValue,
NewValue,
UpdateDate,
UserName)
SELECT 'U',
'AppointmentsWorkshop',
+convert(varchar(100), coalesce(i.UniqueID,d.UniqueID)),
'[JobHours]',
convert(varchar(1000),d.[JobHours]),
convert(varchar(1000),i.[JobHours]),
'20220816 12:32:43:410',
'DELLXPS\ian'
from #ins i full outer join #del d on i.UniqueID = d.UniqueID where ISNULL(i.JobHours],'') <> ISNULL(d.[JobHours],'')
I've tried deleting the trigger & the audit table and then recreating them but no joy. I've also tried copying an existing trigger and just changing the table details but I still get the same error. I'm completely stumped on this and would appreciate some feedback. Many thanks in advance!
Here is the trigger:
/****** Object: Trigger [dbo].[tr_AppointmentsWS] Script Date: 16/08/2022 12:02:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create TRIGGER [dbo].[tr_AppointmentsWS] ON [dbo].AppointmentsWorkshop FOR UPDATE, DELETE
AS
DECLARE #bit INT ,
#field INT ,
#maxfield INT ,
#char INT ,
#fieldname VARCHAR(128) ,
#TableName VARCHAR(128) ,
#AuditTable VARCHAR(128) ,
#PKCols VARCHAR(MAX) ,
#sql VARCHAR(2000),
#UpdateDate VARCHAR(21) ,
#UserName VARCHAR(128) ,
#Type CHAR(1) ,
#PKSelect VARCHAR(MAX)
--Changes required:
-- 1. Change the name of the trigger and the table, above
-- 2. Change #TableName to match the table to be audited
-- 3. Change the #AuditTable to the table holding the changes
SELECT #TableName = 'AppointmentsWorkshop'
SELECT #AuditTable = 'Audit_AppointmentsWS'
-- date and user
SELECT #UserName = SYSTEM_USER ,
#UpdateDate = CONVERT(VARCHAR(8), GETDATE(), 112) + ' ' + CONVERT(VARCHAR(12), GETDATE(), 114)
-- Action
IF EXISTS (SELECT * FROM inserted)
IF EXISTS (SELECT * FROM deleted)
SELECT #Type = 'U'
ELSE
SELECT #Type = 'I'
ELSE
SELECT #Type = 'D'
-- get list of columns
SELECT * INTO #ins FROM inserted
SELECT * INTO #del FROM deleted
-- Get primary key columns for full outer join
SELECT #PKCols = COALESCE(#PKCols + ' and', ' on') + ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk, INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = #TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
-- Get primary key select for insert
SELECT #PKSelect = COALESCE(#PKSelect+'+','') + '+convert(varchar(100), coalesce(i.' + COLUMN_NAME +',d.' + COLUMN_NAME + '))'
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk, INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = #TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
IF #PKCols IS NULL
BEGIN
RAISERROR('no PK on table %s', 16, -1, #TableName)
RETURN
END
SELECT #field = 0, #maxfield = MAX(COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + #Tablename),COLUMN_NAME, 'ColumnID'))
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #TableName
WHILE #field < #maxfield
BEGIN
SELECT #field = MIN(COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + #Tablename),COLUMN_NAME, 'ColumnID'))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + #Tablename),COLUMN_NAME, 'ColumnID') > #field
SELECT #bit = (#field - 1 )% 8 + 1
SELECT #bit = POWER(2,#bit - 1)
SELECT #char = ((#field - 1) / 8) + 1
IF SUBSTRING(COLUMNS_UPDATED(),#char, 1) & #bit > 0 OR #Type IN ('I','D')
BEGIN
SELECT #fieldname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA + '.' + #Tablename),COLUMN_NAME, 'ColumnID') = #field
SELECT #sql = 'insert ' + #AuditTable + '
(Type,
TableName,
PK,
FieldName,
OldValue,
NewValue,
UpdateDate,
UserName)
SELECT ''' + #Type + ''','''
+ #TableName + ''',' + #PKSelect
+ ',''[' + #fieldname + ']'''
+ ',convert(varchar(1000),d.[' + #fieldname + '])'
+ ',convert(varchar(1000),i.[' + #fieldname + '])'
+ ',''' + #UpdateDate + ''''
+ ',''' + #UserName + ''''
+ ' from #ins i full outer join #del d'
+ #PKCols
+ ' where ISNULL(i.[' + #fieldname + '],'''') <> ISNULL(d.[' + #fieldname + '],'''')' --Skip identical values and excludes NULLS vs empty strings
EXEC (#sql)
END
END
Well I finally figured it out. The error is being generated with columns of data type 'decimal' and it is down to the ISNULL section of the last SELECT. I've fixed it by checking for the decimal type and then using the following code (which included a zero rather than an empty sting):
+ ' where ISNULL(i.[' + #fieldname + '],''0'') <> ISNULL(d.[' + #fieldname + '],''0'')' --Skip identical values and excludes NULLS vs empty strings

T-SQL to check and update

Getting error:
Msg 512, Level 16, State 1, Line 48
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Msg 512, Level 16, State 1, Line 87
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Need to check each record in the table and update a table if there is no records = to 0,00. Then update an existing table with current values. I want to be able to track current data and compare with old data.
DECLARE #LocTime DATETIME;
DECLARE #MinDateTime DATETIME;
DECLARE #SystemDateTime DATETIME;
DECLARE #LIR MONEY;
DECLARE #LOAR MONEY;
SELECT #SystemDateTime = SYSDATETIME(); --= '2016-12-07 23:30:00'
SELECT #MinDateTime = DATEADD(mi,-30,#SystemDateTime) --go back half hour of reads, job is running every 10 minutes for overlap
--select #MinDateTime, #SystemDateTime
IF OBJECT_ID(N'tempdb..##LastOver2') IS NOT NULL
BEGIN
DROP TABLE ##LastOver2
END
--make temp table to hold found data
CREATE TABLE ##LastOver2 (ReadDate DATETIME
, FacilityName NVARCHAR(100)
, FacilityID UNIQUEIDENTIFIER
, LastInstantRead MONEY
, LastOverAllRead MONEY
, FacilityTimeZone INT
, FacilityTime DATETIME)
INSERT INTO ##LastOver2 (ReadDate, FacilityName
, FacilityID, LastInstantRead
, LastOverAllRead
, FacilityTimeZone, FacilityTime)
SELECT DISTINCT --why distinct?
fmr.ReadDate, f.Name
, f.FacilityID, fm.LastInstantRead
, fm.LastOverAllRead
, f.Timezone
, #LocTime
FROM [dbo].[Facilities] f WITH (NOLOCK)
JOIN [dbo].[FacilityMeters] fm WITH (NOLOCK)
ON F.FacilityID = FM.FacilityID
JOIN FacilityMeterReadings fmr WITH (NOLOCK)
ON FM.FacilityMeterID = FMR.FacilityMeterID
WHERE --fm.FacilityMeterID = '9268d1af-cc29-432c-9cdb-06c158180d2f'
(fmr.ReadDate >= #MinDateTime and ReadDate <= #SystemDateTime) --including on both side to continue with overlap
and (fm.IsVirtual = 0 and fm.ParentMeterID is NULL)
--and (fm.LastInstantRead = 0.00 and fm.LastOverAllRead = 0.00)
AND f.SuppressMonitoring = 0
select * from ##LastOver2
IF (select LastInstantRead from ##LastOver2) = 0.00 OR (SELECT LastOverAllRead FROM ##LastOver2) = 0.00
BEGIN
--UPDATE dbo.Facilities
--SET SuppressMonitoring = 1
-- FROM dbo.Facilities F
-- JOIN ##LastOver L
-- ON F.FacilityID = l.FacilityID
-- WHERE F.FacilityID = l.FacilityID
DECLARE #body_content NVARCHAR(150);
DECLARE #StartHour NVARCHAR(8) = '08:30:00' ;
DECLARE #StopHour NVARCHAR(8) = '16:00:00';
--why distinct, is it already distinct. Is is supposed to distinct the facility or meter?
DECLARE #SQLScript NVARCHAR(200) = 'SELECT distinct * FROM ##LastOver2 WHERE CONVERT(TIME, FacilityTime) BETWEEN '
+ CHAR(39) + #StartHour + CHAR(39) +' AND ' + CHAR(39) + #StopHour + CHAR(39);
--only looking for reads during day hours? shouldn't use between.
DECLARE #copyRecipients NVARCHAR(100)
SET #body_content = 'Please check the attached file. This was from server: ' + ##SERVERNAME
DECLARE #fileName nvarchar(255);
select #fileName = 'BadReading_' + replace(replace(convert(nvarchar(19),getdate(), 126),':',''),'-','') + '.txt';
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'SQLSupport'
,#recipients = 'Btest#test.com'
--, #recipients = 'jira#cleanenergycollective.atlassian.net'
--, #copy_recipients= #copyRecipients
--, #copy_recipients= 'Bill.Lugaila#easycleanenergy.com;yvonne.lewis#easycleanenergy.com;don.munroe#easycleanenergy.com;Justin.Reed#easycleanenergy.com'
, #query = #SQLScript
, #subject = 'Facility Meter Check and Updating table' --change so easier to see in emails
, #body= #body_content
, #importance= 'High'
, #attach_query_result_as_file = 1
, #query_attachment_filename = #fileName ;
--select #SQLScript
END
ELSE IF (select LastInstantRead from ##LastOver2) != 0.00 OR (SELECT LastOverAllRead FROM ##LastOver2) != 0.00
BEGIN
UPDATE [dbo].[_LastInstant_OverAll_Read]
SET [FacilityName] = lo.FacilityName,
[LastInstantRead] = lo.LastInstantRead,
[LastOverAllRead]= lo.LastOverAllRead,
[Time_Date] = (SELECT CONVERT(DateTime, SysDateTime()))
FROM ##LastOver2 lo
WHERE lo.FacilityName = [dbo].[_LastInstant_OverAll_Read].FacilityName
AND lo.LastInstantRead != [dbo].[_LastInstant_OverAll_Read].LastInstantRead
AND lo.LastOverAllRead != [dbo].[_LastInstant_OverAll_Read].LastOverAllRead
END
the following could be returning multiple rows:
.
.
.
IF
(
SELECT LastInstantRead
FROM ##LastOver2
) = 0.00
OR
(
SELECT LastOverAllRead
FROM ##LastOver2
) = 0.00
.
.
.
IF
(
SELECT LastInstantRead
FROM ##LastOver2
) != 0.00
OR
(
SELECT LastOverAllRead
FROM ##LastOver2
) != 0.00
if you are expecting them to return only 1 row then you will need to fix the issue with the following query:
SELECT DISTINCT --why distinct?
fmr.ReadDate,
f.Name,
f.FacilityID,
fm.LastInstantRead,
fm.LastOverAllRead,
f.Timezone,
#LocTime
FROM [dbo].[Facilities] f WITH (NOLOCK)
JOIN [dbo].[FacilityMeters] fm WITH (NOLOCK) ON F.FacilityID = FM.FacilityID
JOIN FacilityMeterReadings fmr WITH (NOLOCK) ON FM.FacilityMeterID = FMR.FacilityMeterID
WHERE --fm.FacilityMeterID = '9268d1af-cc29-432c-9cdb-06c158180d2f'
(fmr.ReadDate >= #MinDateTime
AND ReadDate <= #SystemDateTime) --including on both side to continue with overlap
AND (fm.IsVirtual = 0
AND fm.ParentMeterID IS NULL)
--and (fm.LastInstantRead = 0.00 and fm.LastOverAllRead = 0.00)
AND f.SuppressMonitoring = 0;

Rework query to include the Schema in the name

I am leeching off this post: Query to list number of records in each table in a database
With this procedure:
CREATE PROCEDURE ListTableRowCounts
AS
BEGIN
SET NOCOUNT ON
CREATE TABLE #TableCounts
(
TableName VARCHAR(500),
CountOf INT
)
INSERT #TableCounts
EXEC sp_msForEachTable
'SELECT PARSENAME(''?'', 1),
COUNT(*) FROM ? WITH (NOLOCK)'
SELECT TableName , CountOf
FROM #TableCounts
ORDER BY TableName
DROP TABLE #TableCounts
END
GO
The procedure works well enough but I need it to output the name as Schema.Name and sort by that.
Is that possible? I'm not sure how to change this but you can see what it is doing below:
I have several instances were the table names are the same from different schemas.
CREATE PROCEDURE ListTableRowCounts
AS
BEGIN
SET NOCOUNT ON
CREATE TABLE #TableCounts
( SchemaName VARCHAR(500),
TableName VARCHAR(500),
CountOf INT
)
INSERT #TableCounts
EXEC sp_msForEachTable
'SELECT PARSENAME(''?'', 2), PARSENAME(''?'', 1),
COUNT(*) FROM ? WITH (NOLOCK)'
SELECT SchemaName, TableName , CountOf
FROM #TableCounts
ORDER BY TableName, SchemaName
DROP TABLE #TableCounts
END
GO
Taking some code from: https://stackoverflow.com/a/1443723/4584335
and from: How do I list all tables in all databases in SQL Server in a single result set?
Could I suggest this one (just in case "sp_msForEachTable" doesn't exist anymore):
declare #sql nvarchar(max);
select #sql = isnull(#sql + N'union all ', '')
+ N'
select b.name as "DB"
,a.name collate Latin1_General_CI_AI
,a.object_id
,a.schema_id
,' + cast(database_id as nvarchar(10)) + N'
,p.[Rows]
from ' + quotename(name) + N'.sys.tables a
join
' + quotename(name) + N'.sys.indexes i
on a.OBJECT_ID = i.object_id
and i.index_id <= 1
join
' + quotename(name) + N'.sys.partitions p
on i.object_id = p.OBJECT_ID
and i.index_id = p.index_id
join sys.databases b
on database_id=' + cast(database_id as nvarchar(10)) + ' '
from sys.databases
where state = 0
and user_access = 0;
exec sp_executesql #sql;

Step through 2 temp tables compare to table

I have a SP that is supposed to compare 2 temp tables generated from a function to another table. My issue is that instead of stepping through each temp table it goes through both at the same time. I am not sure how to write the code to step through each table one at a time to get the desired results.
DROP PROCEDURE uspJudgments;
GO
CREATE PROCEDURE uspJudgments
#fullName varchar(100), #fullName1 varchar(100)
AS
BEGIN
SELECT *
INTO #tmpFullname
FROM dbo.DelimitedSplit8K(#fullName, ',')
SELECT *
INTO #tmpFullname1
FROM dbo.DelimitedSplit8K(#fullName1, ',')
SELECT *
FROM #tmpFullName
SELECT *
FROM #tmpFullName1
DECLARE #MaxRownum int
SET #MaxRownum = (SELECT MAX(ItemNumber) FROM #tmpFullname)
DECLARE #Iter int
SET #Iter = (SELECT MIN(ItemNumber) FROM #tmpFullname)
DECLARE #MaxRownum1 int
SET #MaxRownum1 = (SELECT MAX(ItemNumber) FROM #tmpFullname1)
DECLARE #Iter1 int
SET #Iter1 = (SELECT MIN(ItemNumber) FROM #tmpFullname1)
DECLARE #Name varchar(25)
DECLARE #Name1 varchar(25)
WHILE #Iter <= #MaxRownum AND #iter1 <= #Maxrownum1
BEGIN
SET #Name = (SELECT Item FROM #tmpFullname WHERE ItemNumber = #Iter)
SET #Name1 = (SELECT Item FROM #tmpFullname1 WHERE ItemNumber = #Iter1)
SELECT *
--INTO #tmpDefSelect
FROM defendants_ALL
WHERE combined_name LIKE '%' + #Name + '%' AND combined_name LIKE '%' + #Name1 + '%';
SET #Iter = #Iter + 1
SET #Iter1 = #Iter1 + 1
END
END
DROP TABLE #tmpFullname
DROP TABLE #tmpFullname1
EXEC uspJudgments #fullName = 'grein,smit', #fullName1 = 'joh,jon,j.'
I need to get ALL results for grein -- joh, jon, j. AND smit, joh, jon, j.
Currently the above code only returns grein joh AND smit, jon.. In our database that returns no results for the first combination and 38 results for jonathon smith and jon smith. How do I properly step through each temp table to get the desired results?
You only get the two combinations grein joh and smith jon because of the way you are iterating through #Iter and #iter1. You increment both of them at the same time. You need a nested loop like this:
declare #start_val integer = #iter1
while #Iter <= MaxRownum
begin
set #iter1 = #start_val
while #iter1 <= #Maxrownum1
begin
set #Name = ...
set #Name1 = ...
...
set #iter1 = #iter1 + 1
end
set #Iter = #Iter + 1
end
But I don't think you even need the WHILE loops:
select d.*
from defendants_ALL, #tmpFullname t1, #tmpFullname1 t2
where d.combined_name = t1.Item + ' ' + t2.Item
Or (if you need to still use LIKE):
select d.*
from defendants_ALL, #tmpFullname t1, #tmpFullname1 t2
where d.combined_name like '%' + t1.Item + '%'
and d.combined_name like '%' + t2.Item + '%'
(All SQL is untested...)