What is the format used to represent Date and time in the Goldmine CONTTLOG.LOGSTAMP field? - crm

The two Goldmine tables CONTTLOG and GMTLOG were intended for the GoldSync functionality, however I will be able to use these tables to investigate and report which user made a change and when.
In order to know the when I need to know the format used to represent Date and time in the LOGSTAMP field.
Have asked same question here: https://forums.ivanti.com/s/question/0D54O00007Kfh7MSAR/what-is-the-format-used-to-represent-date-and-time-in-the-logstamp-field

Question is answered in the forum as below, looks like I may want to modernise the SQL:
https://forums.ivanti.com/s/question/0D54O00007Kfh7MSAR/what-is-the-format-used-to-represent-date-and-time-in-the-logstamp-field?language=en_US
In short the syncstamp/logstamp is a base 36 number that when divided by 50 gives you the number of seconds since midnight on 1/1/1990.
A few SQL functions have been posted in the past that can successfully navigate the math of creating/decrypting them.
Here's a set by, I think, Pat Connelly:
CREATE FUNCTION dbo.f_GMSyncStampFromDate
(#datetime DATETIME)
RETURNS VARCHAR(7)
AS
BEGIN
declare #p1 bigint set #p1 = 36
declare #p2 bigint set #p2 = #p1 * #p1
declare #p3 bigint set #p3 = #p2 * #p1
declare #p4 bigint set #p4 = #p3 * #p1
declare #p5 bigint set #p5 = #p4 * #p1
declare #p6 bigint set #p6 = #p5 * #p1
declare #p7 bigint set #p7 = #p6 * #p1
declare #digits char(36)
set #digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
declare #gmstamp varchar(7) set #gmstamp = ''
-- Get the time serial since the beginning of GoldMine time.
declare #s bigint
set #s=datediff(second,'1990-01-01T00:00:00.000',#datetime)*50.0
if (#s / #p7)> 0 return ''
-- Build the base 36 number string.
select #gmstamp = #gmstamp + substring(#digits,1+(#s / #p6),1) set #s=#s%#p6
select #gmstamp = #gmstamp + substring(#digits,1+(#s / #p5),1) set #s=#s%#p5
select #gmstamp = #gmstamp + substring(#digits,1+(#s / #p4),1) set #s=#s%#p4
select #gmstamp = #gmstamp + substring(#digits,1+(#s / #p3),1) set #s=#s%#p3
select #gmstamp = #gmstamp + substring(#digits,1+(#s / #p2),1) set #s=#s%#p2
select #gmstamp = #gmstamp + substring(#digits,1+(#s / #p1),1) set #s=#s%#p1
select #gmstamp = #gmstamp + substring(#digits,1+(#s),1)
-- Remove leading zeros.
while (left(#gmstamp, 1) = '0' )
begin
if (Len(#gmstamp) > 1) set #gmstamp = substring(#gmstamp, 2,len(#gmstamp))
end
return #gmstamp
-- test me
-- select dbo.f_GMSyncStampFromDate(current_timestamp)
END
create function syncstamper(#timestamp char(7))
returns datetime
as
begin
--This formula converts a Goldmine logstamp or syncstamp into a real datetime value. The returned value is
--the GMT time for the stamp, and NOT the regional or daylight saving adjusted time.
--Define all required variables
declare #ts1 char(1)
declare #ts2 char(1)
declare #ts3 char(1)
declare #ts4 char(1)
declare #ts5 char(1)
declare #ts6 char(1)
declare #ts7 char(1)
declare #date datetime
--Break timestamp into component characters
set #ts1 = substring(#timestamp,1,1)
set #ts2 = substring(#timestamp,2,1)
set #ts3 = substring(#timestamp,3,1)
set #ts4 = substring(#timestamp,4,1)
set #ts5 = substring(#timestamp,5,1)
set #ts6 = substring(#timestamp,6,1)
set #ts7 = substring(#timestamp,7,1)
numberVar D1N;
numberVar D2N;
numberVar D3N;
numberVar D4N;
numberVar D5N;
numberVar D6N;
numberVar D7N;
numberVar DF;
datetimeVar timestamp;
numberVar i:=9;
--Create the array of characters
stringVar array digits:= ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K',
'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z')
--Determine the character code for each character
For i:=1 to 36 do
(if D1=digits[i]
then D1N:=i-1);
For i:=1 to 36 do
(if D2=digits[i]
then D2N:=i-1);
For i:=1 to 36 do
(if D3=digits[i]
then D3N:=i-1);
For i:=1 to 36 do
(if D4=digits[i]
then D4N:=i-1);
For i:=1 to 36 do
(if D5=digits[i]
then D5N:=i-1);
For i:=1 to 36 do
(if D6=digits[i]
then D6N:=i-1);
For i:=1 to 36 do
(if D7=digits[i]
then D7N:=i-1);
//Multiply each digit by its factor and divide by 50 to get number of seconds
D1N:=D1N*2176782336/50;
D2N:=D2N*60466176/50;
D3N:=D3N*1679616/50;
D4N:=D4N*46656/50;
D5N:=D5N*1296/50;
D6N:=D6N*36/50;
D7N:=D7N*1/50;
//Add all the seconds together
DF:=D1N+D2N+D3N+D4N+D5N+D6N+D7N;
//Add the time onto the base time of 1st January 1990
timestamp:=DateAdd('s',DF,DateTime(1990,01,01,00,00,00));
//Display time
timestamp
return (#date)
end

Related

Change phone number format

I have phone number field in database. It has already data.
I want to change my phone number format to "XXX-XXX-XXXX"
Current database has no any phone format.
So there may be garbage data. I have already applied validation for new records but now I want to change my existing data also.
Is there any specific way through that I can change my existing data. And make all phone numbers to follow this format.
Please advice.
Create function to remove the non-numeric data and do the formatting
CREATE FUNCTION [UDF_STRIP_NONNUMERIC_DATA](#str VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
WHILE Patindex('%[^0-9]%', #str) > 0
BEGIN
SET #str = Stuff(#str, Patindex('%[^0-9]%', #str), 1, '')
END
RETURN #str
END
You can use STUFF function to inset the - between phone number
Select left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](Phone),4,0,'-'),8,0,'-'),12)
From yourtable
If you are using SQL SERVER 2012+ use can use FORMAT function (thanks to LukStorms, who mentioned it in comment)
SELECT Format(Cast(dbo.[Udf_strip_nonnumeric_data](Phone) AS BIGINT), '###-###-####')
FROM yourtable
To update
Update yourtable
SET phone = left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](Phone),4,0,'-'),8,0,'-'),12)
Demo
declare #str varchar(100)= '9225-123-4567'
select left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](#str),4,0,'-'),8,0,'-'),12)
Result : 922-512-3456
declare #phone varchar(24)
set #phone = '(334)789-4532'
--set #phone = '314789-4532'
--set #phone = '3457894532'
--set #phone = '534-789-4532'
SELECT
LEFT(N,3) + '-' + SUBSTRING(N,4,3) + '-' + RIGHT(N,4)
FROM
(SELECT CAST(CAST((
SELECT SUBSTRING(#phone, Number, 1)
FROM master..spt_values
WHERE Type='p' AND Number <= LEN(#phone) AND
SUBSTRING(#phone, Number, 1) LIKE '[0-9]' FOR XML Path(''))
AS xml) AS varchar(MAX)) as N) as N
Ok, to replace all non-numeric characters, look at this.
Here is a sample script (copied from that link) to show you how it works (You'll need to modify this to fit your table name and column names:
-- Step 1: creates table to use to hold every char in every phone number
if object_id('dbo.tally') is not null drop table dbo.tally
select top 10000 --change to fit max length of phone number
identity(int,1,1) as n
into dbo.tally
from master.dbo.syscolumns sc1,
master.dbo.syscolumns sc2
-- add pk to maximize performance
alter table dbo.tally
add constraint pk_tally_n
primary key clustered (n) with fillfactor = 100
-- Step 2: Create temporary table holding three bad phone numbers
declare #phonetable table
(uniqueid int identity(1,1),
phone_number varchar(500))
insert into #phonetable (phone_number)
select '01234-567-890' union
select '012345 6789ext' union
select 'n/a' union select '...12345.....';
-- Step 3: identify, for every character, whether it is a number or not,
and remove the non-numeric ones
with cte (uniqueid, phone_number, goodchar, badchar) as
( select uniqueid, phone_number,
case when substring(phone_number,N,1) not like '%[^0-9]%'
then substring(phone_number,N,1) end as goodchar,
case when substring(phone_number,N,1) like '%[^0-9]%'
then substring(phone_number,N,1) end as badchar
from #phonetable , Tally
where phone_number like '%[^0-9]%' and N <= len(phone_number) )
select distinct phone_number,
isnull( stuff (
( SELECT '' + goodchar
FROM cte t1
where t1.UniqueID = t2.UniqueID
FOR XML PATH ( '' ) ) , 1 , 0 , '' ) ,'')
as clean_phone_number from cte t2
to display the numbers with formatting, just extract the appropriate pieces and re-concatenate them with the dashes.
Select case len(phone)
When 10 then left(phone, 3) + '-' +
substring(phone, 4,3) + '-' +
substring(phone, 7,4)`
When 7 then left(phone, 3) + '-' +
substring(phone, 4,4)
Else '' end
To create a computed column
Alter table Add Column FormattedPhone as
case len(phone)
When 10 then left(phone, 3) + '-' +
substring(phone, 4,3) + '-' +
substring(phone, 7,4)`
When 7 then left(phone, 3) + '-' +
substring(phone, 4,4)
Else '' end
If you don't mind a UDF
Select [dbo].[udf-Str-Format-Phone]('334)789-4532')
Returns
334-789-4532
The UDF
CREATE FUNCTION [dbo].[udf-Str-Format-Phone] (#S varchar(max))
Returns varchar(25)
AS
Begin
Declare #Return varchar(25)
;with cte0(N) As (Select 1 From (Values(1),(1),(1),(1),(1)) N(N))
, cteN(N) As (Select Top (Len(#S)) Row_Number() over (Order By (Select NULL)) From cte0 N1, cte0 N2)
, cteS(S) As (Select Substring(#S,N,1) From cteN Where Substring(#S, N, 1) LIKE '[0-9]' FOR XML Path(''))
Select #Return = IIf(Len(S)>=10,Stuff(stuff(S,4,0,'-'),8,0,'-'),Stuff(S,4,0,'-')) From cteS
Return #Return
End
-- Syntax : Select [dbo].[udf-Str-Format-Phone]('(334)789-4532') -- Returns 334-789-4532
-- Syntax : Select [dbo].[udf-Str-Format-Phone]('Phone:7894532') -- Returns 789-4532

Cursor Alternative to insert rows returned from a function?

I am sending a concatenated string consisting of a series Tax-Value pair to the database to split and then insert into two columns of a table. I already have a method which uses cursor but i am wondering if there is a better alternative to cursor in this case?
My string looks like this: VAT|10#CST|20#ST|30#VAT|40#WCT|50#OCT|60#FP|70#CD|80#OT|90#
Tax and value are separated by | and Rows are separated by #
I use a function to split this string :
Eg:-
select * from isplit('VAT|10#CST|20#ST|30#VAT|40#WCT|50#OCT|60#FP|70#CD|80#OT|90#','#')
Which returns 9 rows first cell consisting of identity srno and second one consisting of tax|value
Create FUNCTION [dbo].[ISplit](#String nvarchar(4000), #Delimiter char(1))
RETURNS #Results TABLE (SrNo int identity, Items nvarchar(4000))
AS
BEGIN
DECLARE #INDEX INT
DECLARE #SLICE nvarchar(4000)
SELECT #INDEX = 1
IF #String IS NULL RETURN
WHILE #INDEX !=0
BEGIN
SELECT #INDEX = CHARINDEX(#Delimiter,#STRING)
IF #INDEX !=0
SELECT #SLICE = LEFT(#STRING,#INDEX - 1)
ELSE
SELECT #SLICE = #STRING
INSERT INTO #Results(Items) VALUES(#SLICE)
SELECT #STRING = RIGHT(#STRING,LEN(#STRING) - #INDEX)
IF LEN(#STRING) = 0 BREAK
END
RETURN
END
I am planning on splitting the concatenated string into a #temp table and then using a cursor to split it again and store it in #temp1 table and then using this #temp1 to insert the two column values ie. Tax and Value. insert into sometable (tax,value) values(#tax,#value)
select * into #temp from split('VAT|10#CST|20#ST|30#VAT|40#WCT|50#OCT|60#FP|70#CD|80#OT|90#','#')
DECLARE #row varchar(20)
DECLARE #Temp CURSOR
SET #Temp = CURSOR FOR
SELECT *
FROM #temp
OPEN #Temp
FETCH NEXT
FROM #Temp INTO #row
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #row
select * into #temp1 from iSplit(#row,'|')
declare #tax varchar(10)
declare #value varchar(10)
select #tax= items from #temp1 where srno=1
select #value= items from #temp1 where srno=2
insert into sometable (tax,value) values(#tax,#value)
FETCH NEXT
FROM #Temp INTO #row
END
CLOSE #Temp
DEALLOCATE #Temp
is there an alternative to cursor or for statement in this case?
Is this u needed?
without changing the function:
INSERT INTO sometable
(tax,
value)
SELECT Substring(items, 0, Charindex('|', items, 0)) AS tax,
Substring(items, Charindex('|', items, 0) + 1, Len(items)) AS value
FROM [Isplit]('VAT|10#CST|20#ST|30#VAT|40#WCT|50#OCT|60#FP|70#CD|80#OT|90#', '#')
Change the function :
ALTER FUNCTION [dbo].[ISplit](#String nvarchar(4000), #Delimiter char(1))
RETURNS #Results TABLE (SrNo int identity, tax nvarchar(4000),value numeric(22,6))
AS
BEGIN
DECLARE #INDEX INT
DECLARE #SLICE nvarchar(4000)
SELECT #INDEX = 1
IF #String IS NULL RETURN
WHILE #INDEX !=0
BEGIN
SELECT #INDEX = CHARINDEX(#Delimiter,#STRING)
IF #INDEX !=0
SELECT #SLICE = LEFT(#STRING,#INDEX - 1)
ELSE
SELECT #SLICE = #STRING
INSERT INTO #Results(tax,value)
select Substring(#SLICE, 0, Charindex('|', #SLICE, 0)),
Substring(#SLICE, Charindex('|', #SLICE, 0) + 1, Len(#SLICE)) AS value
SELECT #STRING = RIGHT(#STRING,LEN(#STRING) - #INDEX)
IF LEN(#STRING) = 0 BREAK
END
RETURN
END
INSERT INTO sometable
(tax,
value)
SELECT tax,value from Isplit('VAT|10#CST|20#ST|30#VAT|40#WCT|50#OCT|60#FP|70#CD|80#OT|90#', '#')

Using Date.Now in SQL Function

I have a Function like this;
ALTER FUNCTION [dbo].[fngcodeme]
(
#HESAP INT, #DOV INT, #TEKLIF VARCHAR(10), #BAS datetime, #BIT datetime
)
RETURNS FLOAT
AS
BEGIN
DECLARE #Result FLOAT
IF CONVERT(DATETIME, #BIT,103) <= '20110228'
SET #Result = (SELECT SUM(TUTAR)
FROM YAZ..MARDATA.M_HAREKET
WHERE TEMEL_HESAP = #HESAP
AND DOVIZ_KOD = #DOV
AND REF_KOD = 'GC'
AND BACAK_GRUP = 'PERT'
AND ISL_KOD = 1
AND ACIKLAMA LIKE '%' + #TEKLIF + '%'
AND ISL_TAR >= CONVERT(DATETIME, #BAS,103)
AND ISL_TAR <= CONVERT(DATETIME, #BIT,103)
)
ELSE
SET #Result = (SELECT SUM(TUTAR)
FROM YAZ..MARDATA.M_GHAREKET
WHERE TEMEL_HESAP = #HESAP
AND DOVIZ_KOD = #DOV
AND REF_KOD = 'GC'
AND BACAK_GRUP = 'PERT'
AND ISL_KOD = 1
AND ACIKLAMA LIKE '%' + #TEKLIF + '%'
AND ISL_TAR >= CONVERT(DATETIME, #BAS,103)
AND ISL_TAR <= CONVERT(DATETIME, #BIT,103)
)
RETURN #Result
END
M_GHAREKET table is my monthly data table. Every end of the month this table load to M_HAREKET. (And deleted all data in M_GHAREKET)
M_HAREKET is a Big Bucket. M_GHAREKET is small. (I mean M_HAREKET has now over 500.000 data, M_GHAREKET over 4.000)
What i want is for this Function, IF #BAS date's month value is equal DateTime.Now.Month value i want use M_GHAREKET table, else use M_HAREKET table.
How should i change this function like that?
Is it possible like this IF clause with DateTime.Now.Month in SQL Function?
Or i should use in my ASP.NET page? How can i do that?
You can use month and year.
declare #BAS datetime
set #BAS = '2011-03-15'
if month(getdate()) = month(#BAS) and
year(getdate()) = year(#BAS)
You can use DATEDIFF to find the difference between two date in months. This returns the number of time period boundaries crossed so when checking for months it would only return 0 if the two dates are in the same calendar year and month
DECLARE #date1 DATETIME
SET #date1 = '2011-03-01'
SELECT DATEDIFF(MM, #date1, '2011-02-28') -- -1
SELECT DATEDIFF(MM, #date1, '2011-03-20') -- 0
SELECT DATEDIFF(MM, #date1, '2010-03-01') -- -12
So to check that a date is in the same month and year as today (GETDATE()) you could use
DECLARE #date1 DATETIME
SET #date1 = '2011-03-01'
IF DATEDIFF(MM, #date1, GETDATE()) = 0
BEGIN
-- Do your work
END

passing list of name/value pairs to stored procedure

I have a name/value pair in a List<T> and needing to find the best way to pass these to a stored procedure.
Id Name
1 abc
2 bbc
3 cnn
....
...
What is the best way to accomplish this?
One way to handle this in SQL Server 2005 (prior to the availability of table valued parameters) was to pass a delimited list and use a Split function. If you are using a two-column array, you would want to use two different delimiters:
Declare #Values varchar(max)
Set #Values = '1,abc|2,bbc|3,cnn'
With SplitItems As
(
Select S.Value As [Key]
, S2.Value
, Row_Number() Over ( Partition By S.Position Order By S2.Position ) As ElementNum
From dbo.Split(#Values,'|') As S
Outer Apply dbo.Split(S.Value, ',') As S2
)
Select [Key]
, Min( Case When S.ElementNum = 1 Then S.Value End ) As ListKey
, Min( Case When S.ElementNum = 2 Then S.Value End ) As ListValue
From SplitItems As S
Group By [Key]
Create Function [dbo].[Split]
(
#DelimitedList nvarchar(max)
, #Delimiter nvarchar(2) = ','
)
RETURNS TABLE
AS
RETURN
(
With CorrectedList As
(
Select Case When Left(#DelimitedList, Len(#Delimiter)) <> #Delimiter Then #Delimiter Else '' End
+ #DelimitedList
+ Case When Right(#DelimitedList, Len(#Delimiter)) <> #Delimiter Then #Delimiter Else '' End
As List
, Len(#Delimiter) As DelimiterLen
)
, Numbers As
(
Select Row_Number() Over ( Order By c1.object_id ) As Value
From sys.columns As c1
Cross Join sys.columns As c2
)
Select CharIndex(#Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position
, Substring (
CL.List
, CharIndex(#Delimiter, CL.list, N.Value) + CL.DelimiterLen
, CharIndex(#Delimiter, CL.list, N.Value + 1)
- ( CharIndex(#Delimiter, CL.list, N.Value) + CL.DelimiterLen )
) As Value
From CorrectedList As CL
Cross Join Numbers As N
Where N.Value < Len(CL.List)
And Substring(CL.List, N.Value, CL.DelimiterLen) = #Delimiter
)
Another way to handle this without table-valued parameters is to pass Xml as an nvarchar(max):
Declare #Values nvarchar(max)
Set #Values = '<root><Item Key="1" Value="abc"/>
<Item Key="2" Value="bbc"/>
<Item Key="3" Value="cnn"/></root>'
Declare #docHandle int
exec sp_xml_preparedocument #docHandle output, #Values
Select *
From OpenXml(#docHandle, N'/root/Item', 1)
With( [Key] int, Value varchar(10) )
Take a look at Arrays and Lists in SQL Server 2008 to get some ideas
SQL Server 2008 also supports this multi row values syntax
create table #bla (id int, somename varchar(50))
insert #bla values(1,'test1'),(2,'Test2')
select * from #bla
i endup using foreach <insert>
This could done through three ways.
User Defined Table Type
Json Object Parsing
XML Parsing
I tried with the first option and passed a list of pairs in User Defined Table Type. This works for me. I am posting here, it might help someone else.
The first challenge for me was to pass the list of key value pair data structure and second to loop through the list and insert the record in a table.
Step 1 : Create a User Defined Table Type. I have created with a name 'TypeMetadata'. As it is custom type, I created two attributes of type nvarchar. You can create one of type integer and second of type nvarchar.
-- Type: metadata ---
IF EXISTS(SELECT * FROM SYS.TYPES WHERE NAME = 'TypeMetadata')
DROP TYPE TypeMetadata
GO
CREATE TYPE TypeMetadata AS TABLE (
mkey nvarchar (50),
mvalue nvarchar (50)
);
GO
Step 2 : Then I created a stored procedure with name 'createfiled'
-- Procedure: createtext --
CREATE PROCEDURE [dbo].[createfield]
#name nvarchar(50),
#text nvarchar(50),
#order int,
#type nvarchar(50),
#column_id int ,
#tid int,
#metadataList TypeMetadata readonly
AS
BEGIN
--loop through metadata and insert records --
DECLARE #mkey nvarchar(max);
DECLARE #mvalue nvarchar(max);
DECLARE mCursor CURSOR LOCAL FAST_FORWARD
FOR
SELECT mkey, mvalue
FROM #metadataList;
OPEN mCursor;
FETCH NEXT FROM mCursor INTO #mkey, #mvalue; -- Initial fetch attempt
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO template_field_metadata (name, value, template_field_id, isProperty) values (#mkey, #mvalue, 1, 0)
PRINT 'A new metadata created with id : ' + cast(SCOPE_IDENTITY() as nvarchar);
FETCH NEXT FROM mCursor INTO #mkey, #mvalue; -- Attempt to fetch next row from cursor
END;
CLOSE mCursor;
DEALLOCATE mCursor;
END
GO
Step 3: finally I executed the stored procedure like;
DECLARE #metadataToInsert TypeMetadata;
INSERT INTO #metadataToInsert VALUES ('value', 'callVariable2');
INSERT INTO #metadataToInsert VALUES ('maxlength', '30');
DECLARE #fid INT;
EXEC [dbo].[createfield] #name = 'prefagent', #text = 'Pref Agent', #order = 1 , #type= 'prefagent', #column_id = 0, #tid = 49, #metadataList =#metadataToInsert;

Stored proc in .net dataset class vs studio management

Morning all. Got myself a simple query which returns ten rows in SQL Server Management Studio. I call the stored proc by right clicking it and feeding in the parameters.
The results are returned immediately.
In .NET we have set up a dataset class, added a table adapter whose select is this same procedure. I pass in the very same parameters and the execution times out after the standard 30 seconds. It continues to run immediately when called in sql server management studio.
Any ideas why the execution time is seemingly infinite in the .net dataset class.
The query is very simple.
ALTER PROCEDURE [dbo].[usp_GetPostcodeAnalysis]
-- Add the parameters for the stored procedure here
#startDate DATETIME,
#endDate DATETIME,
#customerID INTEGER = NULL,
#siteID INTEGER = -1
AS
DECLARE #itemTypeID INT
SELECT #itemTypeID=ItemTypeID FROM dbo.ItemTypes WHERE ItemTypeName = 'Advert'
DECLARE #SQL NVARCHAR(4000)
BEGIN
SET #SQL = 'SELECT at.ActionTypeName,
COUNT(*) AS "Count"
FROM CustomerSites cs JOIN Items i
ON cs.SiteID = i.SiteID
JOIN Actions a
ON a.ItemID = i.ItemID
JOIN ActionTypes at
ON a.ActionTypeID = at.ActionTypeID
WHERE a.DateAndTime BETWEEN #1 AND #2
AND i.ItemTypeID = #iti
AND at.ActionTypeName IN (''List view'', ''Full view'', ''Email enquiry'', ''Print view'', ''Directions'')'
IF #customerID IS NOT NULL
SET #SQL = #SQL + ' AND i.CustomerID = #c'
IF #siteID > -1
SET #SQL = #SQL + ' AND i.SiteID = #s'
SET #SQL = #SQL + ' GROUP BY
at.ActionTypeName
ORDER BY
at.ActionTypeName'
EXECUTE sp_executesql #SQL,
N'#1 DATETIME, #2 DATETIME, #iti INT, #c INT, #s INT',
#startDate, #endDate, #itemTypeID, #customerID, #siteID

Resources