Related
I have the following query in a job, it is scheduled to run every hour of L-V.
All the records that are made in the table in the FCH_FIN field have an exact time, for example: 7:00:00 to 19:00:00.
Then I create a temporary table and pass the data from my original table, and I want to go through my temporary table to get the difference in time between the system time using GETDATE () and the time of the record in the FCH_FIN field, if this is less then update active to 0.
Query:
DECLARE #count INT;
DECLARE #fch2 DATETIME;
DECLARE #seconds INT;
CREATE table #Suple
(
ID INT PRIMARY KEY NOT NULL,
ACTIVO NCHAR(10) NOT NULL,
FCH_INICIO DATETIME NOT NULL,
FCH_FIN DATETIME NOT NULL
);
INSERT INTO #Suple
SELECT *
FROM Original
WHERE ACTIVO = 1
AND CONVERT(DATE, FCH_FIN) = CONVERT(DATE, GETDATE());
SELECT #count = COUNT(*) FROM #Suple;
WHILE #count > 0
BEGIN
SELECT
#seconds = DATEDIFF(S, GETDATE(),FCH_FIN)
FROM
#Suple
WHERE
ACTIVO = 1
AND CONVERT(DATE, FCH_FIN) = CONVERT(DATE, GETDATE())
IF (#seconds < 3)
UPDATE Original
SET ACTIVO = 0
DELETE TOP(1) FROM #Suple
SET #count = (SELECT COUNT(*) FROM #Suple);
END
DROP TABLE #Suple
This query does not update anything
Table:
Can someone help me?
Why are you doing this in a loop in the first place? But look at your update statement. You are updating every single row in Original every iteration of the loop. But this should not be using a loop at all. Your ENTIRE code block here can be reduced to a single statement. You don't need temp tables or loops for this.
Also using shorthand in date functions is a challenge.
Update Original
where ACTIVO = 0
AND CONVERT(DATE, FCH_FIN) = CONVERT(DATE, GETDATE())
and DATEDIFF(Second, GETDATE(),FCH_FIN) < 3
I have a datetime field in my SQL table. I have created a procedure that takes count as a variable and generates records for the table. If the count is 5 it will generate 5 records.The logic i want is that when i provide 5 as an input parameter the datetime field in the table should be autofilled with values
12/20/2015 9:00
12/20/2015 11:00
12/20/2015 13:00
12/20/2015 15:00
12/20/2015 17:00
So every time a record is inserted into a table,the 2 hours of time should be added.
Recursive CTEs are one way to create records on the fly. The key here is to create an anchor (this is the first SELECT inside the CTE, which is your starting point). And an exit check (which is the WHERE clause).
Read up on MAXRECURSION if you want to create more than 100 records at a time.
Example
DECLARE #RecordsRequired INT = 5;
DECLARE #BaseDateTime SMALLDATETIME = GETDATE();
WITH [Sample] AS
(
/* This CTE uses recursion to create the required number of
* records.
*/
SELECT
1 AS RowNumber,
#BaseDateTime AS [DateTime]
UNION ALL
SELECT
RowNumber + 1 AS RowNumber,
DATEADD(HOUR, 2, [DateTime]) AS [DateTime]
FROM
[Sample]
WHERE
RowNumber < #RecordsRequired
)
SELECT
RowNumber,
[DateTime]
FROM
[Sample]
;
You could also look into WHILE blocks.
Use this code:
------------------ INPUT ------------------------
declare #start_date datetime = '01/01/2000 14:00'
declare #loops int = 5
-------------------------------------------------
declare #i int = 0
while (#i < #loops) begin
select dateadd(hour, #i * 2, #start_date)
set #i = #i + 1
end
Try this without LOOP
Declare #count int = 5,
#incrementer int =2 -- in case if you want to change the incrementer
SELECT Dateadd(hh, num * #incrementer, dates)
FROM (SELECT Cast(CONVERT(VARCHAR(20), Dateadd(dd, 1, Getdate()), 111)
+ ' 9:00 AM' AS DATETIME) AS Dates,
num
FROM (VALUES(0),(1),(2),(3),(4),(5)) TC (num)) A
WHERE num <= #count - 1
SQL FIDDLE DEMO
Please find the sample code below, it contains the logic that you needed. Hope it helps!!
--Create a temp table for sample output
CREATE TABLE #temp
(
CreatedDate datetime
)
--Declaring variables
DECLARE #Count int
DECLARE #TimeCounter int
--intializing values
SET #Count=5
SET #TimeCounter=0
WHILE(#Count>0)
BEGIN
--SELECT getdate()+1
insert into #temp(#temp.CreatedDate) Select DATEADD(hour,#TimeCounter,getdate())
SET #TimeCounter=#TimeCounter+2
SET #Count=#Count-1
END
--Final values
SELECT * FROM #temp tmp
--Dropping table
DROP TABLE #temp
This is one of those problems that's best solved with a numbers table / function. Much less code than recursion or loops, usually faster for anything non-trivial and more reusable too.
The core code you want is
CREATE PROCEDURE usp_PopulateAppointments
(
#StartDateTime datetime2(3),
#Records int,
#Interval int = 120 --Time between appointment slots in minutes. Default to 2h if not manually specified.
)
INSERT INTO Appointments
SELECT
DATEADD(m, #Interval * Number, #StartDateTime)
FROM dbo.udfNumbers(0, #Recs)
I've assumed in this a numbers function that takes #StartAt and #NumberResults. I use one derived from Adam's final code in the comments on http://dataeducation.com/you-require-a-numbers-table/ - in my experience it's faster than a real table, and takes less space too.
Create Table dates
(
datetimefield datetime not null
)
go
Create Procedure FillDateTimeField
#insertxrows int
AS
begin
Declare #LastDateTimeInserted as datetime
set #LastDateTimeInserted = (select isnull(max(datetimefield),getdate()) from Dates)
;WITH norows AS (
SELECT 1 as num, Dateadd(hour,2,#LastDateTimeInserted) as FirstRecord
UNION ALL
SELECT num + 1, dateadd(hour,2,firstrecord) FROM
norows
WHERE num < #insertxrows
)
insert into dates
select firstrecord from norows
end
I'm hoping to create a view in a SQL Server database. It will be based on one table which looks like this:
Date (primary key) | Minimum (decimal) | Target (decimal) | Achieved (decimal)
As a month progresses, e.g. January 2015, that table will be populated daily.
I want to create a view which looks like this (say we are only up to 2nd January 2015):
2015-01-01 | Minimum | Target | Achieved | Calculated Column
2015-01-02 | Minimum | Target | Achieved | Calculated Column
2015-01-03 | null | null | null | Calculated Column
...
2015-01-31 | null | null | null | Calculated Column
So, essentially returning data from the table where available but then also adding a row for each future day too. Don't worry about the calculated column, I think I can do that bit.
Does that makes sense? Grateful for any help.
Thank you.
You can generate a calendar table which has all dates in the ranges of interest for it. Then you just join to that table with a condition on the month. See this web site on how to make a calendar table. There are many ways to do it.
Edit: Per this site, you could use a CTE before your query to create a temporary calendar to join to:
declare #start datetime,
#end datetime
set #start = '2006-01-01'
set #end = '2007-01-01'
;
with calendar(date,isweekday, y, q,m,d,dw,monthname,dayname,w) as
(
select #start ,
case when datepart(dw,#start) in (1,7) then 0 else 1 end,
year(#start),
datepart(qq,#start),
datepart(mm,#start),
datepart(dd,#start),
datepart(dw,#start),
datename(month, #start),
datename(dw, #start),
datepart(wk, #start)
union all
select date + 1,
case when datepart(dw,date + 1) in (1,7) then 0 else 1 end,
year(date + 1),
datepart(qq,date + 1),
datepart(mm,date + 1),
datepart(dd,date + 1),
datepart(dw,date + 1),
datename(month, date + 1),
datename(dw, date + 1),
datepart(wk, date + 1) from calendar where date + 1< #end
)
select * from calendar option(maxrecursion 10000)
Based on your question, apparently you need to use a stored procedure or a function since your output must have an end date. So basically, you need a stored procedure or function that accepts a date parameter and outputs a table containing the data you want. Something similar to the following may help:
USE TEST -- Test database. You may want to replace this with your DB name
GO
CREATE PROCEDURE proStackOverflowQuestion25287207 #date date -- To try it, execute: exec proStackOverflowQuestion25287207 '2008-02-11' -- or any date of your choice.
AS
BEGIN
DECLARE #monthdays INT, #dateday INT, #marker INT, #noRecordDate NVARCHAR(30)
SET #marker = 1 -- we start the first day of the month
SET #monthdays = DATEDIFF(dd,#date,(DATEADD(mm,1,#date))) -- get the number of days in the concerned month
SET #dateday = DAY(#date)
CREATE TABLE #temTbl(
[Date] [date] PRIMARY KEY,
[Minimum] [decimal](18, 0) NULL,
[Target] [decimal](18, 0) NULL,
[Achieved] [decimal](18, 0) NULL,
[Calculated] [decimal](18, 0) NULL
)
WHILE #marker <= #monthdays
BEGIN
--insert new record in temp table
IF exists(SELECT * FROM MyTable WHERE DAY([Date]) = #marker AND MONTH([Date]) = MONTH(#date) AND YEAR([Date]) = YEAR(#date))
INSERT INTO #temTbl SELECT *, null FROM MyTable WHERE DAY([Date]) = #marker --*** you may need to replace null by your Calculated value...
ELSE
BEGIN
SET #noRecordDate = CONVERT(NVARCHAR(4), YEAR(#date)) + '-' + CONVERT(NVARCHAR(2), MONTH(#date)) + '-' + CONVERT(NVARCHAR(2), #marker)
INSERT INTO #temTbl([Date], Minimum, [Target], Achieved, Calculated) VALUES (#noRecordDate, null, null, null, null) -- you may need to replace the last null by your calculated value...
END
-- increment marker
SET #marker = #marker + 1
END
SELECT * FROM #temTbl
END
I need to make a temporary table that holds of range of dates, as well as a couple of columns that hold placeholder values (0) for future use. The dates I need are the first day of each month between $startDate and $endDate where these variables can be several years apart.
My original sql statement looked like this:
select dbo.FirstOfMonth(InsertDate) as Month, 0 as Trials, 0 as Sales
into #dates
from customer
group by dbo.FirstOfMonth(InsertDate)
"FirstOfMonth" is a user-defined function I made that pretty much does what it says, returning the first day of the month for the provided date with the time at exactly midnight.
This produced almost exactly what I needed until I discovered there were occasionally gaps in my dates where I had a few months were there were no records insert dates. Since my result must still have the missing months I need a different approach.
I have added the following declarations to the stored procedure anticipating their need for the range of the dates I need ...
declare $startDate set $startDate = select min(InsertDate) from customer
declare $endDate set $endDate = select max(InsertDate) from customer
... but I have no idea what to do from here.
I know this question is similar to this question but, quite frankly, that answer is over my head (I don't often work with SQL and when I do it tends to be on older versions of SQL Server) and there are a few minor differences that are throwing me off.
I needed something similar, but all DAYS instead of all MONTHS.
Using the code from MatBailie as a starting point, here's the SQL for creating a permanent table with all dates from 2000-01-01 to 2099-12-31:
CREATE TABLE _Dates (
d DATE,
PRIMARY KEY (d)
)
DECLARE #dIncr DATE = '2000-01-01'
DECLARE #dEnd DATE = '2100-01-01'
WHILE ( #dIncr < #dEnd )
BEGIN
INSERT INTO _Dates (d) VALUES( #dIncr )
SELECT #dIncr = DATEADD(DAY, 1, #dIncr )
END
This will quickly populate a table with 170 years worth of dates.
CREATE TABLE CalendarMonths (
date DATETIME,
PRIMARY KEY (date)
)
DECLARE
#basedate DATETIME,
#offset INT
SELECT
#basedate = '01 Jan 2000',
#offset = 1
WHILE (#offset < 2048)
BEGIN
INSERT INTO CalendarMonths SELECT DATEADD(MONTH, #offset, date) FROM CalendarMonths
SELECT #offset = #offset + #offset
END
You can then use it by LEFT joining on to that table, for the range of dates you require.
I would probably use a Calendar table. Create a permanent table in your database and fill it with all of the dates. Even if you covered a 100 year range, the table would still only have ~36,525 rows in it.
CREATE TABLE dbo.Calendar (
calendar_date DATETIME NOT NULL,
is_weekend BIT NOT NULL,
is_holiday BIT NOT NULL,
CONSTRAINT PK_Calendar PRIMARY KEY CLUSTERED (calendar_date)
)
Once the table is created, just populate it once in a loop, so that it's always out there and available to you.
Your query then could be something like this:
SELECT
C.calendar_date,
0 AS trials,
0 AS sales
FROM
dbo.Calendar C
WHERE
C.calendar_date BETWEEN #start_date AND #end_date AND
DAY(C.calendar_date) = 1
You can join in the Customers table however you need to, outer joining on FirstOfMonth(InsertDate) = C.calendar_date if that's what you want.
You can also include a column for day_of_month if you want which would avoid the overhead of calling the DAY() function, but that's fairly trivial, so it probably doesn't matter one way or another.
This of course will not work in SQL-Server 2000 but in a modern database where you don't want to create a permanent table. You can use a table variable instead creating a table so you can left join the data try this. Change the DAY to HOUR etc to change the increment type.
declare #CalendarMonths table (date DATETIME, PRIMARY KEY (date)
)
DECLARE
#basedate DATETIME,
#offset INT
SELECT
#basedate = '01 Jan 2014',
#offset = 1
INSERT INTO #CalendarMonths SELECT #basedate
WHILE ( DATEADD(DAY, #offset, #basedate) < CURRENT_TIMESTAMP)
BEGIN
INSERT INTO #CalendarMonths SELECT DATEADD(HOUR, #offset, date) FROM #CalendarMonths where DATEADD(DAY, #offset, date) < CURRENT_TIMESTAMP
SELECT #offset = #offset + #offset
END
A starting point of a useful kludge to specify a range or specific list of dates:
SELECT *
FROM
(SELECT CONVERT(DateTime,'2017-1-1')+number AS [Date]
FROM master..spt_values WHERE type='P' AND number<370) AS DatesList
WHERE DatesList.Date IN ('2017-1-1','2017-4-14','2017-4-17','2017-12-25','2017-12-26')
You can get 0 to 2047 out of master..spt_values WHERE type='P', so that's five and a half year's worth of dates if you need it!
Tested below and it works, though it's a bit convoluted.
I assigned arbitrary values to the dates for the test.
DECLARE #SD smalldatetime,
#ED smalldatetime,
#FD smalldatetime,
#LD smalldatetime,
#Mct int,
#currct int = 0
SET #SD = '1/15/2011'
SET #ED = '2/02/2012'
SET #FD = (DATEADD(dd, -1*(Datepart(dd, #SD)-1), #sd))
SET #LD = (DATEADD(dd, -1*(Datepart(dd, #ED)-1), #ED))
SET #Mct = DATEDIFF(mm, #FD, #LD)
CREATE TABLE #MyTempTable (FoM smalldatetime, Trials int, Sales money)
WHILE #currct <= #Mct
BEGIN
INSERT INTO #MyTempTable (FoM, Trials, Sales)
VALUES
(DATEADD(MM, #currct, #FD), 0, 0)
SET #currct = #currct + 1
END
SELECT * FROM #MyTempTable
DROP TABLE #MyTempTable
For SQL Server 2000, this stackoverflow post looks promising for a way to temporarily generate dates calculated off of a start and end date. It's not exactly the same but quite similar. This post has a very in-depth answer on truncating dates, if needed.
In case anyone stumbles on this question and is working in PostgreSQL instead of SQL Server 2000, here is how you might do it there...
PostgreSQL has a nifty series generating function. For your example, you could use this series of all days instead of generating an entire calendar table, and then do groupings and matchups from there.
SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a);
dates
------------
2004-02-05
2004-02-12
2004-02-19
(3 rows)
SELECT * FROM generate_series('2008-03-01 00:00'::timestamp,
'2008-03-04 12:00', '10 hours');
generate_series
---------------------
2008-03-01 00:00:00
2008-03-01 10:00:00
2008-03-01 20:00:00
2008-03-02 06:00:00
2008-03-02 16:00:00
2008-03-03 02:00:00
2008-03-03 12:00:00
2008-03-03 22:00:00
2008-03-04 08:00:00
(9 rows)
I would also look into date_trunc from PostgreSQL using 'month' for the truncator field to maybe refactor your original query to easily match with a date_trunc version of the calendar series.
select top (datediff(D,#start,#end)) dateadd(D,id-1,#start)
from BIG_TABLE_WITH_NO_JUMPS_IN_ID
declare #start datetime
set #start = '2016-09-01'
declare #end datetime
set #end = '2016-09-30'
create table #Date
(
table_id int identity(1,1) NOT NULL,
counterDate datetime NULL
);
insert into #Date select top (datediff(D,#start,#end)) NULL from SOME_TABLE
update #Date set counterDate = dateadd(D,table_id - 1, #start)
The code above should populate the table with all the dates between the start and end. You would then just join on this table to get all of the dates needed. If you only needed a certain day of each month, you could dateadd a month instead.
SELECT P.Id
, DATEADD ( DD, -P.Id, P.Date ) AS Date
FROM (SELECT TOP 1000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) AS Id, CAST(GETDATE () AS DATE) AS Date FROM master.dbo.spt_values) AS P
This query returns a table calendar for the last 1000 days or so. It can be put in a temporary or other table.
Create a table variable containing a date for each month in a year:
declare #months table (reportMonth date, PRIMARY KEY (reportMonth));
declare #start date = '2018', #month int = 0; -- base 0 month
while (#month < 12)
begin
insert into #months select dateAdd(month, #month, #start);
select #month = #month + 1;
end
--verify
select * from #months;
This is by far the quickest method I have found (much quicker than inserting rows 1 by 1 in a WHILE loop):
DECLARE #startDate DATE = '1900-01-01'
DECLARE #endDate DATE = '2050-01-01'
SELECT DATEADD(DAY, sequenceNumber, #startDate) AS TheDate
INTO #TheDates
FROM (
SELECT ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n + 10000*tenthousands.n AS sequenceNumber
FROM
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n),
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n),
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) hundreds(n),
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thousands(n),
(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tenthousands(n)
WHERE ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n + 10000*tenthousands.n <= DATEDIFF(day, #startDate, #endDate)
) theNumbers
SELECT *
FROM #TheDates
ORDER BY TheDate
The recursive answer:
DECLARE #startDate AS date = '20220315';
DECLARE #endDate AS date = '20230316'; -- inclusive
WITH cte_minutes(dt)
AS (
SELECT
DATEFROMPARTS(YEAR(#startDate), MONTH(#startDate), 1)
UNION ALL
SELECT
DATEADD(month, 1, dt)
FROM
cte_minutes
WHERE DATEADD(month, 1, dt) < #endDate
)
SELECT
dt
into #dates
FROM
cte_minutes
WHERE
dt >= #startDate
AND
dt <= #endDate
OPTION (MAXRECURSION 2000);
DROP TABLE dbo.#dates
I have the following table in my database:
tbl1
PK
ClientID
ScheduleDay
Time1Start
Time1Stop
Time2Start
Time2Stop
Time3Start
Time3Stop
Status
Here is some sample data
ID ClientID ScheduleDay Time1Start Time1Stop Time2Start Time2Stop Time3Start Time3Stop
-- -------- ----------- ---------- --------- ---------- --------- ---------- ---------
1 3 Sunday 0000 0800 1000 1300 NULL NULL
2 3 Monday 0000 2359 NULL NULL NULL NULL
3 3 Tuesday 1000 1200 1330 1700 1900 2200
4 3 Wednesday 0000 0800 NULL NULL NULL NULL
5 3 Thursday 0800 1200 NULL NULL NULL NULL
6 3 Friday 0400 0800 0900 1600 NULL NULL
The Time fields are CHAR(4) since I am storing the time in a military format.
What I need to accomplish is this; for any given ClientID, insert one or more records into a schedule table with the time value of the record being within the time frames in tbl1. For example, scheduling ClientID 3 on Tuesday, the time scheduled could be 1120.
In the event that multiple records need to be inserted, the times scheduled should not be any closer than one hour.
Any and all help is appreciated!
Here's my best guess as to what you're trying to do. The first two parts of the CTE are really just to get things into a form similar to what FlyingStreudel suggests. Ideally, you should change the database to match that format instead of doing this through CTEs. That will make this significantly simpler and is better for data integrity as well.
Next, I just get the distinct start times in hour increments. You could do that by joining to a Numbers table as well if you can't use CTEs (you didn't mention the version of SQL Server that you're using).
Finally, I grab one of those start times at random, using the RAND function and ROW_NUMBER. You'll want to set a good seed value for RAND().
;WITH TimesAsTimes AS
(
SELECT
ScheduleDay,
CAST(SUBSTRING(T1.Time1Start, 1, 2) + ':' + SUBSTRING(T1.Time1Start, 3, 2) AS TIME) AS time_start,
CAST(SUBSTRING(T1.Time1Stop, 1, 2) + ':' + SUBSTRING(T1.Time1Stop, 3, 2) AS TIME) AS time_stop
FROM
tbl1 T1
WHERE
T1.Time1Start IS NOT NULL
UNION ALL
SELECT
ScheduleDay,
CAST(SUBSTRING(T2.Time2Start, 1, 2) + ':' + SUBSTRING(T2.Time2Start, 3, 2) AS TIME) AS time_start,
CAST(SUBSTRING(T2.Time2Stop, 1, 2) + ':' + SUBSTRING(T2.Time2Stop, 3, 2) AS TIME) AS time_stop
FROM
tbl1 T2
WHERE
T2.Time2Start IS NOT NULL
UNION ALL
SELECT
ScheduleDay,
CAST(SUBSTRING(T3.Time3Start, 1, 2) + ':' + SUBSTRING(T3.Time3Start, 3, 2) AS TIME) AS time_start,
CAST(SUBSTRING(T3.Time3Stop, 1, 2) + ':' + SUBSTRING(T3.Time3Stop, 3, 2) AS TIME) AS time_stop
FROM
tbl1 T3
WHERE
T3.Time3Start IS NOT NULL
),
PossibleTimeStarts AS
(
SELECT
ScheduleDay,
time_start,
time_stop
FROM
TimesAsTimes TAT
UNION ALL
SELECT
ScheduleDay,
DATEADD(hh, 1, time_start) AS time_start,
time_stop
FROM
PossibleTimeStarts PTS
WHERE
DATEADD(hh, 1, time_start) <= DATEADD(hh, -1, PTS.time_stop)
),
PossibleTimesWithRowNums AS
(
SELECT
ScheduleDay,
time_start,
ROW_NUMBER() OVER(PARTITION BY ScheduleDay ORDER BY ScheduleDay, time_start) AS row_num,
COUNT(*) OVER(PARTITION BY ScheduleDay) AS num_rows
FROM
PossibleTimeStarts
)
SELECT
*
FROM
PossibleTimesWithRowNums
WHERE
row_num = FLOOR(RAND() * num_rows) + 1
First of all you may want to try a schema like
tbl_sched_avail
PK id INT
FK client_id INT
day INT (1-7)
avail_start varchar(4)
avail_end varchar(4)
This way you are not limited to a finite number of time fences.
As far as checking the schedules availability -
CREATE PROCEDURE sp_ins_sched
#start_time varchar(4),
#end_time varchar(4),
#client_id INT,
#day INT
AS
BEGIN
DECLARE #can_create BIT
SET #can_create = 0
DECLARE #fence_start INT
DECLARE #fence_end INT
--IS DESIRED TIME WITHIN FENCE FOR CLIENT
DECLARE c CURSOR FOR
SELECT avail_start, avail_end FROM tbl_sched_avail
WHERE client_id = #client_id
AND day = #day
OPEN c
FETCH NEXT FROM c
INTO #fence_start, #fence_end
WHILE ##FETCH_STATUS = 0 AND #can_create = 0
BEGIN
IF #start_time >= #fence_start AND #start_time < #fence_end
AND #end_time > #fence_start AND <= #fence_end
SET #can_create = 1
FETCH NEXT FROM c
INTO #fence_start, #fence_end
END
CLOSE c
DEALLOCATE c
IF #can_create = 1
BEGIN
--insert your schedule here
END
END
As far as the code for actually inserting the record I would need to know more about the tables in the database.