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

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.

Related

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

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.

Problems trying to return records from SELECT statement using Postgresql

I am NEW to Postgresql. I downloaded v9.5 of Postgresql a couple of days ago and finding this DB pretty challenging in just trying to get my result set back from a pretty length SELECT statement. I'm using the pgAdmin III product and hoping that I can see my result data but to no avail.
I've inherited this code and trying to make changes and trying NOT to HARD CODE the lines where the variables are being used if I can avoid it.
I've been googling about this for 2 days but again to no avail and I've tried many different variations but still not doing something right. Any help/direction would be appreciated.
Here is the error I'm getting:
********** Error **********
ERROR: query has no destination for result data
SQL state: 42601
Hint: If you want to discard the results of a SELECT, use PERFORM instead.
Context: PL/pgSQL function getrecords() line 14 at SQL statement
Here is my code (sorry for the length of the query):
CREATE OR REPLACE FUNCTION getRecords() RETURNS TABLE (
title TEXT,
Number_of_visits BIGINT,
Daily_Visit_Total_hours TEXT,
First_Aid_Visits BIGINT,
First_Aid_Total_hours TEXT,
Major_Accident_Visits BIGINT,
Major_Accident_Total_hours TEXT,
Illness_Visits BIGINT,
Illness_Total_hours TEXT,
Medication_Administration_Visits BIGINT,
Medication_Administration_Total_hours TEXT,
Specialization_Visits BIGINT,
Specialization_Total_hours TEXT,
Diabetic_Visits BIGINT,
Diabetic_Total_Hours TEXT) AS $$
#variable_conflict use_variable
DECLARE
SYEAR_DATE NUMERIC;
START_DATE DATE;
END_DATE DATE;
SCHOOL_ID NUMERIC;
BEGIN
SYEAR_DATE := 2015;
START_DATE := '2015-08-01';
END_DATE := '2015-12-31';
SCHOOL_ID := 002;
SELECT DISTINCT
'999 - DISTRICT TOTALS',
dailyVisitTotal.count as Number_of_visits,
round (dailyVisitTotal.duration_total / 60, 2) || 'hrs' as Daily_Visit_Total_hours,
firstAid.count as First_Aid_Visits,
round (firstAid.duration_total / 60, 2) || 'hrs' as First_Aid_Total_hours,
majorAcc.count as Major_Accident_Visits,
round (majorAcc.duration_total / 60, 2) || 'hrs' as Major_Accident_Total_hours,
illness.count as Illness_Visits,
round (illness.duration_total / 60, 2) || 'hrs' as Illness_Total_hours,
medicationAdminTotal.count as Medication_Administration_Visits,
round (medicationAdminTotal.duration_total / 60, 2) || 'hrs' as Medication_Administration_Total_hours,
specTotal.count as Specialization_Visits,
round (specTotal.duration_total / 60, 2) || 'hrs' as Specialization_Total_hours,
diabeticTotal.count as Diabetic_Visits,
round (diabeticTotal.duration_total / 60, 2) || 'hrs' as Diabetic_Total_Hours
FROM student_enrollment se
LEFT JOIN (
SELECT
se.syear,
count(*),
sum(coalesce(log_field20::numeric, 0)) as duration_total
FROM custom_field_log_entries sle
INNER JOIN student_enrollment se
on (sle.source_id=se.student_id
and se.custom_9 is null
and se.syear=SYEAR_DATE
--and se.syear=2015
and se.end_date is null)
WHERE
--student_field_id = 400000941
legacy_field_id = 400000941
and log_field2::date between START_DATE and END_DATE
--and log_field2::date between '2015-08-01' and '2015-12-31'
and (log_field20 ~ '^[0-9]+$' or log_field20 is null)
GROUP BY se.syear
) dailyVisitTotal
on (se.syear = dailyVisitTotal.syear)
LEFT JOIN (
SELECT
se.syear,
count(*),
sum(coalesce(log_field20::numeric, 0)) as duration_total
FROM custom_field_log_entries sle
INNER JOIN student_enrollment se
on (sle.source_id=se.student_id
and se.custom_9 is null
and se.syear=SYEAR_DATE
--and se.syear=2015
and se.end_date is null)
WHERE
--student_field_id = 400000941
legacy_field_id=400000941
and log_field2::date between START_DATE and END_DATE
--and log_field2::date between '2015-08-01' and '2015-12-31'
and (log_field20 ~ '^[0-9]+$' or log_field20 is null)
and log_field4='Y'
GROUP BY se.syear
) firstAid
on (se.syear = firstAid.syear)
LEFT JOIN (
SELECT
se.syear,
count(*),
sum(coalesce(log_field20::numeric, 0)) as duration_total
FROM custom_field_log_entries sle
INNER JOIN student_enrollment se
on (sle.source_id=se.student_id
and se.custom_9 is null
and se.syear=SYEAR_DATE
--and se.syear=2015
and se.end_date is null)
WHERE
--student_field_id = 400000941
legacy_field_id=400000941
and log_field2::date between START_DATE and END_DATE
--and log_field2::date between '2015-08-01' and '2015-12-31'
and (log_field20 ~ '^[0-9]+$' or log_field20 is null)
and log_field9='Y'
GROUP BY se.syear
) majorAcc
on (se.syear = majorAcc.syear)
LEFT JOIN (
SELECT
se.syear,
count(*),
sum(coalesce(log_field20::numeric, 0)) as duration_total
FROM custom_field_log_entries sle
INNER JOIN student_enrollment se
on (sle.source_id=se.student_id
and se.custom_9 is null
and se.syear=SYEAR_DATE
--and se.syear=2015
and se.end_date is null)
WHERE
--student_field_id = 400000941
legacy_field_id=400000941
and log_field2::date between START_DATE and END_DATE
--and log_field2::date between '2015-08-01' and '2015-12-31'
and (log_field20 ~ '^[0-9]+$' or log_field20 is null)
and log_field5='Y'
GROUP BY se.syear
) illness
on (se.syear = illness.syear)
LEFT JOIN (
SELECT
se.syear,
count(*),
sum(coalesce(log_field2::numeric, 0)) as duration_total
FROM custom_field_log_entries sle
INNER JOIN student_enrollment se
on (sle.source_id=se.student_id
and se.custom_9 is null
and se.syear=SYEAR_DATE
--and se.syear=2015
and se.end_date is null)
WHERE
--student_field_id = 400001237
legacy_field_id=400001237
and log_field5::date between START_DATE and END_DATE
--and log_field5::date between '2015-08-01' and '2015-12-31'
and (log_field2 ~ '^[0-9]+$' or log_field2 is null)
GROUP BY se.syear
) medicationAdminTotal
on (se.syear = medicationAdminTotal.syear)
LEFT JOIN (
SELECT
se.syear,
count(*),
sum(coalesce(log_field11::numeric, 0)) as duration_total
FROM custom_field_log_entries sle
INNER JOIN student_enrollment se
on (sle.source_id=se.student_id
and se.custom_9 is null
and se.syear=SYEAR_DATE
--and se.syear=2015
and se.end_date is null)
WHERE
--student_field_id = 400009202
legacy_field_id=400009202
and log_field3::date between START_DATE and END_DATE
--and log_field3::date between '2015-08-01' and '2015-12-31'
and (log_field11 ~ '^[0-9]+$' or log_field11 is null)
GROUP BY se.syear
) specTotal
on (se.syear = specTotal.syear)
LEFT JOIN (
SELECT
se.syear,
count(*),
sum(coalesce(log_field14::numeric, 0)) as duration_total
FROM custom_field_log_entries sle
INNER JOIN student_enrollment se
on (sle.source_id=se.student_id
and se.custom_9 is null
and se.syear=SYEAR_DATE
--and se.syear=2015
and se.end_date is null)
WHERE
--student_field_id = 400009003
legacy_field_id=400009003
and log_field1::date between START_DATE and END_DATE
--and log_field1::date between '2015-08-01' and '2015-12-31'
and (log_field14 ~ '^[0-9]+$' or log_field14 is null)
GROUP BY se.syear
) diabeticTotal
on (se.syear = diabeticTotal.syear)
WHERE
se.syear = SYEAR_DATE
--se.syear = 2015
and se.end_date is null
and se.custom_9 is null
and se.syear=SYEAR_DATE
--and se.syear=2015
and se.end_date is null
and (
specTotal.duration_total is not null
or dailyVisitTotal.duration_total is not null
or diabeticTotal.duration_total is not null
or medicationAdminTotal.duration_total is not null
)
ORDER BY 1;
END $$ LANGUAGE 'plpgsql';
SELECT * FROM getRecords();
Add RETURN QUERY before your query. That should tell postgres to return the records from your query.
BEGIN
SYEAR_DATE := 2015;
START_DATE := '2015-08-01';
END_DATE := '2015-12-31';
SCHOOL_ID := 002;
RETURN QUERY SELECT DISTINCT
'999 - DISTRICT TOTALS',
dailyVisitTotal.count as Number_of_visits,
round (dailyVisitTotal.duration_total / 60, 2) || 'hrs' as Daily_Visit_Total_hours,
firstAid.count as First_Aid_Visits,
...

Find the missing hour with Lag analytic function

I have to find the missing hour in my table , for frequency = 1 I have to find a record per hour, if it's not the case, I have to display the missing hour.
here's my code
declare #StartDate datetime declare #EndDate datetime declare #now datetime set #now = getdate() set #StartDate = dateadd(day,-30,#now) set #EndDate = dateadd(day,-2,#now) Select Flow.Id,Flow.ComponentId, Frequency.Name frequencyName, Flow.MeasurementDate as MeasurementDate, LAG(MeasurementDate) OVER (ORDER BY MeasurementDate) LagValue, abs( DATEDIFF (hour, MeasurementDate, LAG(MeasurementDate) OVER (ORDER BY MeasurementDate) ) ) DifferenceDate , (CASE WHEN DATEDIFF (hour, MeasurementDate, LAG(MeasurementDate) OVER (ORDER BY MeasurementDate) ) > '1' THEN 'Yes' ELSE 'No' END) AS Gap into #tab1 FROM Data.dbo.Flow inner join Data.dbo.Component on flow.ComponentId = Component.Id inner join Data.dbo.Frequency on Flow.Frequency = Frequency.Id Where flow.LoaderCode='TOT' and Flow.Frequency='1' and ScheduledVolume IS NOT NULL and MeasurementDate between #StartDate and #EndDate --and DATEDIFF (hour, MeasurementDate, LAG(MeasurementDate) OVER (ORDER BY MeasurementDate) ) >1 Group By Frequency.Name, Flow.MeasurementDate, Flow.ComponentId select * from #tab1
--if i right understood then try this
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
DECLARE #now DATETIME
IF OBJECT_ID('Tempdb..#tab1') IS NOT NULL
BEGIN
DROP TABLE #tab1
END
SET #now = GETDATE()
SET #StartDate = GETDATE() - 30
SET #EndDate = GETDATE() - 2
SELECT Flow.Id ,
Flow.ComponentId ,
Frequency.Name AS frequencyName ,
CONVERT(DATE, Flow.MeasurementDate) AS [Measurement Date] ,
DATEPART(HOUR, Flow.MeasurementDate) AS [Measurement Hour] ,
COALESCE(LAG(DATEPART(HOUR, Flow.MeasurementDate)) OVER ( PARTITION BY CONVERT(DATE, MeasurementDate) ORDER BY DATEPART(HOUR,
MeasurementDate) ),
0) AS [Measurement Previous Hour]
INTO #tab1
FROM Data.dbo.Flow
INNER JOIN Data.dbo.Component ON Flow.ComponentId = Component.Id
INNER JOIN Data.dbo.Frequency ON Flow.Frequency = Frequency.Id
WHERE Flow.LoaderCode = 'TOT'
AND Flow.Frequency = '1'
AND ScheduledVolume IS NOT NULL
AND CONVERT(DATE, MeasurementDate) BETWEEN CONVERT(DATE, #StartDate)
AND CONVERT(DATE, #EndDate)
SELECT T.* ,
CASE WHEN ( T.[Measurement Hour] - T.[Measurement Previous Hour] ) > 1
THEN ( T.[Measurement Hour] - T.[Measurement Previous Hour] - 1 )
ELSE 0
END AS [Missing Hours]
FROM #tab1a AS T
WHERE ( T.[Measurement Hour] - T.[Measurement Previous Hour] ) > 1

TSQL get unique (not overlapping) datetime ranges

This is a question like this: TSQL get overlapping periods from datetime ranges but with a different result request.
This is the table:
create table period (
id int,
starttime datetime,
endtime datetime,
type varchar(64)
);
insert into period values (1,'2013-04-07 8:00','2013-04-07 13:00','Work');
insert into period values (2,'2013-04-07 14:00','2013-04-07 17:00','Work');
insert into period values (3,'2013-04-08 8:00','2013-04-08 13:00','Work');
insert into period values (4,'2013-04-08 14:00','2013-04-08 17:00','Work');
insert into period values (5,'2013-04-07 10:00','2013-04-07 11:00','Holyday'); /* 1h overlapping with 1*/
insert into period values (6,'2013-04-08 10:00','2013-04-08 20:00','Transfer'); /* 6h overlapping with 3 and 4*/
insert into period values (7,'2013-04-08 11:00','2013-04-08 12:00','Test'); /* 1h overlapping with 3 and 6*/
I need the unique not overlapping datetime ranges table.
In the before example the result would be:
'2013-04-07 08:00','2013-04-07 13:00'
'2013-04-07 14:00','2013-04-07 17:00'
'2013-04-08 08:00','2013-04-08 20:00'
It is not very important if could be time fragmentation such as:
'2013-04-08 08:00','2013-04-08 13:00'
'2013-04-08 12:00','2013-04-08 20:00'
--EDIT--
Another example:
create table period (
id int,
starttime datetime,
endtime datetime,
type varchar(64)
);
insert into period values (1,'2013-06-13 8:30','2013-06-13 12:30','');
insert into period values (2,'2013-06-13 8:38','2013-06-13 12:38','');
insert into period values (3,'2013-06-13 13:18','2013-06-13 17:45','');
insert into period values (4,'2013-06-13 13:30','2013-06-13 17:30','');
insert into period values (5,'2013-06-13 20:00','2013-06-13 23:59','');
this should return:
2013-06-13 08:30 - 2013-06-13 12:38
2013-06-13 13:18 - 2013-06-13 17:45
2013-06-13 20:00 - 2013-06-13 23:59
But you have only one non-overlapping period, or did I understand the question wrong?
select *
from period t
where id in (
select t1.id
from period t1
join period t2 on t1.id <> t2.id
where t2.endtime <= t1.starttime or t2.starttime >= t1.endtime
group by t1.id
having count(*) + 1 = (select count(*) from period)
)
Result:
'2013-04-07 14:00','2013-04-07 17:00'
Update: Ok, so you want to merge overlapping ranges. Try this:
select starttime, endtime
from period
where id in (
select t1.id
from period t1
join period t2 on t1.id <> t2.id
where t2.endtime < t1.starttime or t2.starttime > t1.endtime
group by t1.id
having count(*) + 1 = (select count(*) from period)
)
union all
select min(start), max(fin) from (
select
case when t2.starttime < t1.starttime then t2.starttime else t1.starttime end as start,
case when t2.endtime < t1.endtime then t1.endtime else t2.endtime end as fin
from period t1
join period t2 on t1.id < t2.id
where t2.endtime >= t1.starttime and t2.starttime <= t1.endtime) overlaps
group by datepart(dd, start), datepart(dd, fin)
I found this solution... I think this is not the best way, but seems to work.
DECLARE #union_unique TABLE (id INT IDENTITY(1, 1) primary key ,starttime datetime,endtime datetime)
DECLARE #idset TABLE (id int)
DECLARE #i int
SET #i = 1
IF (SELECT COUNT(*) FROM period) > 0
WHILE (#i <= (SELECT MAX(id) FROM period))
BEGIN
delete from #idset
insert into #idset
select distinct t2.id
from period t1
join #union_unique t2 on convert(date, t1.starttime)=convert(date, t2.starttime)
where t1.id=#i and
(
t1.starttime >= t2.starttime and t1.starttime <= t2.endtime
or
t1.endtime >= t2.starttime and t1.endtime <= t2.endtime
or
t1.starttime <= t2.starttime and t1.endtime >= t2.endtime
)
if(select count(*) from #idset)=0
insert into #union_unique (starttime, endtime) select starttime, endtime from period where id=#i
else
BEGIN
insert into #union_unique (starttime, endtime)
select
min(starttime),
max(endtime)
from (
select starttime, endtime from #union_unique where id in (select id from #idset)
union
select starttime, endtime from period where id=#i
) alll
delete from #union_unique where id in (select id from #idset)
END
SET #i = #i + 1
END
select * from #union_unique order by starttime

How to formulate T-SQL to exclude duplicates?

I am trying to develop a query to just return non-duplicate records so that I can add these to my database, but I keep getting the duplicate record error.
I tried your solution but am still getting duplicate error problem. I deleted the 35 rows which were duplicate. What else could be causing this? Here is my query. Part of the confusion I think is that measureid is a single column in j5c_MasterMeasures, but this value comes from two fields in j5c_ListBoxMeasures_Sys.
CREATE TABLE #GOOD_RECORDS3 (STUDENTID VARCHAR(50), MEASUREDATE SMALLDATETIME, MEASUREID VARCHAR(100),
score_10 VARCHAR(100))
INSERT INTO #GOOD_RECORDS3
select A.studentid, A.measuredate, B.measurename+' ' +B.LabelName, A.score_10
from [J5C_Measures_Sys] A join [J5C_ListBoxMeasures_Sys] B on A.MeasureID = B.MeasureID
except
select A.studentid, A.measuredate, B.measurename+' ' +B.LabelName, A.score_10
from [J5C_Measures_Sys] A join [J5C_ListBoxMeasures_Sys] B on A.MeasureID = B.MeasureID
GROUP BY A.studentid, A.measuredate, B.measurename, B.LabelName, A.score_10
having COUNT(A.score_10) > 1
delete #GOOD_RECORDS3
from #GOOD_RECORDS3 a
join sysobjects so on so.name = 'J5C_Measures_Sys' AND so.type = 'u'
join syscolumns sc on so.id = sc.id and sc.name = 'score_10'
join [J5C_MeasureNamesV2_Sys] v on v.Score_field_id = sc.name
WHERE A.SCORE_10 IS NOT NULL AND A.STUDENTID IS NOT NULL AND A.MEASUREID IS NOT NULL
and exists (select 1 from J5C_MasterMeasures M
where M.StudentID = A.StudentID
and M.MeasureID = A.MeasureID)
Insert into J5C_MasterMeasures (studentid, measuredate, measureid, nce)
select A.studentid, A.measuredate, a.MEASUREID, A.score_10
from #GOOD_RECORDS3 a
join sysobjects so on so.name = 'J5C_Measures_Sys' AND so.type = 'u'
join syscolumns sc on so.id = sc.id and sc.name = 'score_10'
join [J5C_MeasureNamesV2_Sys] v on v.Score_field_id = sc.name
WHERE A.SCORE_10 IS NOT NULL AND A.STUDENTID IS NOT NULL AND A.MEASUREID IS NOT NULL
You have not menstioned the specifics of the unique constraint on J5C_MasterMeasures. Therefore, I assumed that all four columns being inserted were part of the constraint. In addition, your use of Except leads me to believe that you are using SQL Server 2005 or later. In addition, it is not clear how the join to J5C_MeasureNamesV2_Sys fits into the design or solution.
With GoodRecords As
(
Select A.StudentId
, A.measuredate
, B.measurename+ ' ' +B.LabelName
, A.score_10 As NCE
From [J5C_Measures_Sys] A
Join [J5C_ListBoxMeasures_Sys] B
On A.MeasureID = B.MeasureID
Where A.StudentId Is Not Null
And A.Score_10 Is Not Null
And A.MeasureId Is Not Null
Group By A.StudentId
, A.MeasureDate
, B.MeasureName+ ' ' +B.LabelName
, A.score_10
Having Count(A.Score_10) = 0
)
Insert J5C_MasterMeasures ( StudentId, MeasureData, MeasureId, NCE )
Select GR.StudentId, GR.MeasureData, GR.MeasureId, GR.NCE
From GoodRecords As GR
Join [J5C_MeasureNamesV2_Sys] v
On v.Score_field_id = 'Score_10'
Where Not Exists (
Select 1
From J5C_MasterMeasures As J1
Where J1.StudentId = GR.StudentId
And J1.MeasureData = GR.MeasureData
And J1.MeasureId = GR.MeasureId
And J1.NCE = GR.NCE
)