Upload
others
View
10
Download
0
Embed Size (px)
Citation preview
IntroductionRoger Abram has worked for (C)Systems for the past eight years as Project Manager and Senior Technical Lead. Prior to joining (C)Systems, Roger worked for several associations in the Washington D.C. area for 28 years in membership and information services departments. He first started using iMISin 1998.
SQL Database ManagementSQL Scripting (stored procedures, views, functions, etc.)iMIS Database UpgradesDatabase Conversions to iMISTask Centre Installations and DevelopmentDay to Day iMIS supportiMerge proceduresCustomer Service AlertsiEmailOther Third Party Products
Course Topics• SQL expressions for IQA that most everyone can
use• Building a SQL view for use in custom-built business
objects• Building and using stored procedures for event
pricing• How to build simple stored procedures to ensure
data integrity • Things to be aware of and to avoid when creating
and scheduling stored procedures• SQL Scripts that help manage and troubleshoot
iMIS/SQL Issues
Terminology To Be Used Frequently In Class
• SQL – Structured Query Language• iMIS Database – Holds all of the iMIS tables, data,
stored procedures, views, business objects, etc.• Tables – Where data is stored• Fields – Data structure for a piece of information in a
table• Views – Dynamic tables • Business Objects – Similar to SQL Views except they
are used to generate a C# code file which is made available to the runtime environment
• Stored Procedures - SQL statements and logic needed to perform a commonly performed task
Terminology To Be Used Frequently in Class
• Variable – A Transact-SQL variable is an object that can hold a single data value of a specific type. Used in stored procedures.
• Parameter – Parameters are used to exchange data between stored procedures and functions and the application or tool that called the stored procedure or function.
• Function – Reusable SQL logic that hides the steps and the complexity from other code.
• IQA - Intelligent Query Architect (IQA) is a query-building tool that extracts data from the iMIS database. IQA simplifies query-building tasks by providing a user-friendly interface that makes it easy for a user with limited SQL experience to build queries and reports.
• SQL Management Studio (SSMS) - is a software application that is used for configuring, managing, and administering all components within Microsoft SQL Server. The tool includes both script editors and graphical tools which work with objects and features of the server.
SQL Expressions In IQA Queries
Let’s Get Started!
• You first start by creating a basic IQA query that contains all the fields you want in the final version of the query that will include SQL Expressions.
• From the Query Summary Page, copy the SQL statement to use as a reference and paste into a query Window in SQL Management Studio.
• By using SQL expressions, you have more control over the output from an IQA query.
SQL Expressions In IQA Queries
• In your SQL Management Studio, create the SQL expressions that you want to use in your IQA.
• Copy and paste your SQL expressions into your IQA query and test.
SQL Expressions In IQA Queries
Common use of SQL Expressions• CASE statement to control output of empty
fields.• REPLACE function used to replace the a line
return with an HTML <BR/>.• Concatenation to link literal text contained in
single quotes with field data.• Use of HTML (em, strong, a href, etc.)
SQL Expressions In IQA Queries• CAST and CONVERT (used to convert fields
into different data types. Text to Date for example.
• Date functions such as DATEADD, MONTH, YEAR, etc. to format dates or use in CASE statements
• LTRIM, RTRIM, LEN and other string functions
• ISDATE, ISNULL, ISEMPTY, and many other SQL functions
SQL Expressions In IQA Queries
• SQL Expressions can’t be edited, but must be recreated if you want to change them.
• The column sort feature (clicking the column heading) may not produce desired order
• iMIS is finicky about the SQL expressions structure. Sometimes it requires trial and error.
SQL Expressions In IQA Queries
Lab #1 – Details of requirements for lab exercise will be announced in class.
Creating a SQL ViewIn SQL, a view is a virtual table based on the result-set of an SQL statement. A viewcontains rows and columns, just like a real table. The fields in a view are fields from one or more real tables in the database.
In our case, we’ll be creating a SQL view that will be then turned into a Business Object that can then be used throughout iMIS including IQA. Allows for more flexibility in creating the logic for an IQA query.
Creating a Simple SQL ViewUSE [imis20]GO
/****** Object: View [dbo].[vw_NIUG_Spouse_Names_All] Script Date: 10/1/2015 8:44:53 AM ******/SET ANSI_NULLS ONGO
SET QUOTED_IDENTIFIER ONGO
CREATE view [dbo].[vw_NIUG_Spouse_Names_All]
as
/*HISTORY OF VIEW -- Who created it, what purpose does it serve, what dependencies might it have*/
Select n.ID, n.Full_Name, n.Last_First, Case when (nd.Spouse = '' or nd.Spouse Is Null) Then 'No Spouse Listed' Else nd.Spouse End as SpouseNameFrom Name nLeft Outer Join Name_Demo nd on n.ID = nd.IDWhere n.Member_Record = 1 and n.COMPANY_RECORD = 0
NOTE: WHEN CREATING VIEWS OR STORED PROCEDURES, INCLUDE YOUR COMPANY ACRONYNM IN THE NAME TO EASILY IDENTIFY THAT IT IS A CUSTOM OBJECT.
Creating a Simple SQL View
Above are the results of a very simple SQL view that lists records in the database and whether or not they have spouses.
Create A New IQA With The New Business Object
Lab #2 – Details of requirements for lab exercise will be announced in class.
Create Stored Procedure for Event Pricing
Why Use A Stored Procedure For Event Pricing?
You can implement complex pricing promotions, such as 50% off additional registrants from a given company. If iMIS cannot find the stored procedure specified or if it fails, default pricing applies.
Requirements:
Your procedure must take one parameter but could take two. If your procedure takes one parameter, iMIS passes in the registrant ID only; if it takes two parameters, iMIS passes in the registrant ID and the event ID, in that order. Using both parameters lets you manage multiple events in the same procedure.
Create Stored Procedure for Event Pricing
CREATE PROCEDURE [dbo].[asi_TestGetRegistrantClass]@RegistrantID varchar(10),@EventID varchar(10)
ASBEGIN
SELECT case @EventId when ‘SPRCONF’ then ‘M’ else ‘NM’ ENDEND
Above: sample procedure given by ASI athttp://docs.imis.com/20.2/#!configuringcontentitembasedeventregistration.htm
Create Stored Procedure for Event Pricing
CREATE PROCEDURE [dbo].[proc_NiUG_TestGetRegistrantClass]
@RegistrantID varchar(10)AS
BEGIN
SELECT case @RegistrantID when '194' then 'SP' else 'NM' ENDEND
Create Stored Procedure for Event Pricing – Example 1
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROC [dbo].[Proc_csys_determine_registration_class] (@RegistrantID VARCHAR(10))AS/*Rev : 2Date : October 30, 2014Purpose : Updated SQL Code and added two dependent views:
vw_CSYS_Committee_Chapter_Group_Product_Codesvw_CSYS_Registered_Annual_Meeting
By : Roger Abram (C)Systems*//*Rev : 1Date : October 28, 2014Purpose : To update reg class for complimentary categories or Newly Certified : membersBy : Lori B (C)Systems*/
-- to test: exec proc_CSYS_Determine_Registration_Class '00016'SET nocount ON
DECLARE @MemberType VARCHAR(10)DECLARE @Category VARCHAR(10)DECLARE @Status VARCHAR(1)DECLARE @RegID VARCHAR(10)DECLARE @Registrant_Class VARCHAR(5)DECLARE @paidThru DATETIMEDECLARE @CAFMCertDate DATETIMEDECLARE @CAPACertDate DATETIME
Create Stored Procedure for Event Pricing – Example 1
SELECT @MemberType = MEMBER_TYPE,@Category = CATEGORY,@Status = STATUS,@PaidThru = PAID_THRU
FROM NAMEWHERE ID = @RegistrantID
SELECT @Category = CATEGORYFROM NAMEWHERE ID = @RegistrantID
SELECT @Status = STATUSFROM NAMEWHERE ID = @RegistrantID
SELECT @paidThru = PAID_THRUFROM NAMEWHERE ID = @RegistrantID
SELECT @MemberType = MEMBER_TYPE,@Category = CATEGORY,@Status = STATUS,@PaidThru = PAID_THRU
FROM NAMEWHERE ID = @RegistrantID
SELECT @CAFMCertDate = CertificationDateFROM AdditionalWHERE ID = @RegistrantID
SELECT @CAPACertDate = CAPACertificationDateFROM AdditionalWHERE ID = @RegistrantID
Create Stored Procedure for Event Pricing – Example 1
-- SELECT * FROM ADDITIONAL--select top 1 @RegID = ST_ID from Orders where ORDER_TYPE_CODE = 'MEETING' and ST_ID = @RegistrantIDSELECT @Registrant_Class = CASE
WHEN @RegistrantID IN (SELECT IDFROM ActivityWHERE Activity_Type = 'COMMITTEE'
AND Other_Code = 'BOD'AND Thru_date >= Getdate()) THEN 'C-BRD'
WHEN @RegistrantID IN (SELECT IDFROM ActivityWHERE Activity_Type = 'COMMITTEE'
AND Product_Code IN (SELECT Product_CodeFROM vw_CSYS_Committee_Chapter_Group_Product_Codes)
AND Thru_date >= Getdate()) THEN 'CHBRD'WHEN @CAFMCertDate >= Getdate() - 365 THEN 'NCERT'WHEN @CAPACertDate >= Getdate() - 365 THEN 'NCERT'WHEN @CAFMCertDate >= Getdate() - 730
AND @RegistrantID NOT IN (SELECT ST_IDFROM vw_CSYS_Registered_Annual_Meeting) THEN 'NCERT'
WHEN @CAFMCertDate >= Getdate() - 730AND @RegistrantID NOT IN (SELECT ST_ID
FROM vw_CSYS_Registered_Annual_Meeting) THEN 'NCERT'WHEN @MemberType IN ( 'CERT', 'ELDER', 'RET', 'ASSOC' )
AND @Status = 'A' THEN 'M'WHEN @MemberType IN ( 'CERT', 'ELDER', 'RET', 'ASSOC' )
AND @Status = 'I' THEN 'NM'ELSE 'NM'
END
SELECT @Registrant_Class
Create Stored Procedure for Event Pricing – Example 2
/****** Object: StoredProcedure [dbo].[proc_CSYS_Determine_Registrant_Class] Script Date: 9/29/2015 1:48:23 PM ******/SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Proc_csys_determine_registrant_class] @RegistrantId VARCHAR(10)AS
/*Rev : 2Date : March 30, 2015Purpose : Modified script to find anyone with a date in YP_Expiration >= current date to be YP reg class as per Ed DeAngelo.By : Nadine W (C) SystemsRev : 1Date : March 27, 2015Purpose : Add in criteria for YP registrant class. Note YP takes priority as per Ed DeAngeloBy : Nadine W (C) Systems
*/SET NOCOUNT ON
DECLARE @CO_ID VARCHAR (10)
Create Stored Procedure for Event Pricing – Example 2
SET @CO_ID = ''
SELECT @CO_ID = CO_IDFROM NAMEWHERE ID = @RegistrantId
DECLARE @Member_Type VARCHAR (5)
SET @Member_Type = ''
SELECT @Member_Type = Member_TypeFROM NAMEWHERE ID = @RegistrantId
/*
For any company that is considered a ‘sustaining sponsor’, every individual within the company should get the early member registration rate with registering onlineA sustaining sponsor is defined by a company record having the sponsor.sustaining field = ‘1’All other people registering should follow the rules of member/non-member registrant class determination.I assume we will need to create a new registrant class for these sustaining sponsors and define the early pricing for them separately, correct?
Registrant class: SPONC
*/-- drop table #SponsorCompanies-- select * from #SponsorcompaniesSET NOCOUNT ON
Create Stored Procedure for Event Pricing – Example 2
SELECT n.IDINTO #SponsorCompaniesFROM NAME n
JOIN Sponsor sON s.ID = n.ID
WHERE s.Sustaining = 1AND n.Status = 'A'AND n.COMPANY_RECORD = 1
BEGINSELECT CASE
WHEN @CO_ID > ''AND @CO_ID IN (SELECT ID
FROM #SponsorCompanies)AND @RegistrantId IN (SELECT ID
FROM Name_IndvWHERE Isnull (yp_expiration, '01/01/1900') < Getdate()) THEN 'SS'
WHEN @CO_ID > ''AND @CO_ID IN (SELECT ID
FROM #SponsorCompanies)AND @RegistrantId IN (SELECT ID
FROM Name_IndvWHERE yp_expiration >= Getdate()) THEN 'YP'
WHEN @CO_ID NOT IN (SELECT IDFROM #SponsorCompanies)
AND @Member_Type IN (SELECT MEMBER_TYPEFROM Member_TypesWHERE MEMBER_RECORD = 1)
AND @RegistrantId IN (SELECT IDFROM Name_IndvWHERE Isnull (yp_expiration, '01/01/1900') < Getdate()) THEN 'M‘
Create Stored Procedure for Event Pricing – Example 2
WHEN @CO_ID NOT IN (SELECT IDFROM #SponsorCompanies)
AND @Member_Type IN (SELECT MEMBER_TYPEFROM Member_TypesWHERE MEMBER_RECORD IN ( 1, 0 ))
AND @RegistrantId IN (SELECT IDFROM Name_IndvWHERE yp_expiration >= Getdate()) THEN 'YP'
ELSE 'NM'END
END
-- EXEC proc_CSYS_Determine_Registrant_Class '20140'
Create Stored Procedure for Event Pricing
Lab #3 – Details of requirements for lab exercise will be announced in class.
Stored Procedures – Data Integrity
Data integrity refers to maintaining and assuring the accuracy and consistency of data over its entire life-cycle, and is a critical aspect to the design, implementation, and usage of any system which stores, processes, or retrieves data. The term data integrity is broad in scope and may have widely different meanings depending on the specific context – even under the same general umbrella of computing.
Stored Procedures – Data Integrity
Data Integrity –
• Bad data in the database• Data that needs to be manipulated to follow an
organization’s business rules• Database Maintenance –
–Purge Name Records–Purge Unused Users–Purge Unused Contacts–Rebuild Indexes
Stored Procedures – Data Integrity(Procedure 1 - Various client scripts)
/****** Object: StoredProcedure [dbo].[proc_NiUG_ADD_SALUTATION] Script Date: 10/02/2015 07:54:21 ******/SET ANSI_NULLS OFFGOSET QUOTED_IDENTIFIER OFFGO
CREATE PROCEDURE [dbo].[proc_NiUG_ADD_SALUTATION]AS
SELECT n.ID,CONVERT(VARCHAR(10), 'FORMAL') SALUTATION_TYPE,CASEWHEN n.PREFIX IN ( 'Mr.', 'Mrs.', 'Ms.' ) THEN n.PREFIX + ' ' + n.LAST_NAMEWHEN n.PREFIX = 'Hon.'
AND COMPANY LIKE '%Supreme%' THEN 'Justice ' + n.LAST_NAMEWHEN n.PREFIX = 'Hon.'
AND COMPANY NOT LIKE '%Supreme%' THEN 'Judge ' + n.LAST_NAMEWHEN n.PREFIX = 'Prof.' THEN 'Professor ' + n.LAST_NAMEWHEN n.PREFIX = 'Brig. Gen.' THEN 'Brigadeer General ' + n.LAST_NAMEELSE n.PREFIX + ' ' + n.LAST_NAME
END SALUTATION_TEXTINTO #salFROM awFellow a,
NAME nWHERE a.ID = n.ID
AND a.ID NOT IN (SELECT IDFROM Name_SalutationWHERE Salutation_Type = 'FORMAL')
Stored Procedures – Data Integrity(Procedure 1 - Various client scripts)
INSERT INTO #salSELECT n.ID,
'INFORMAL' SALUTATION_TYPE,CASEWHEN n.PREFIX NOT LIKE '%Hon%'
AND n.INFORMAL NOT IN ( ' ', NULL ) THEN n.INFORMALWHEN n.PREFIX NOT LIKE '%Hon%'
AND n.INFORMAL IN ( ' ', NULL ) THEN n.FIRST_NAMEWHEN ( n.PREFIX LIKE '%Hon%'
AND n.COMPANY LIKE '%Supreme%' ) THEN ( 'Justice ' + n.LAST_NAME )WHEN ( n.PREFIX LIKE '%Hon%'
AND n.COMPANY NOT LIKE '%Supreme%' ) THEN ( 'Judge ' + n.LAST_NAME )ELSE ''
END SALUTATION_TEXTFROM #sal s,
NAME nWHERE s.ID = n.ID
AND n.ID NOT IN (SELECT IDFROM Name_SalutationWHERE Salutation_Type = 'INFORMAL')
INSERT INTO Name_SalutationSELECT *,
NULLFROM #sal
Stored Procedures – Data Integrity(Procedure 2 - Various client scripts)
SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO
CREATE PROCEDURE [dbo].[Proc_niug_sync_subscriptions_paid_thru]AS
UPDATE SubscriptionsSET PAID_THRU = s.BILL_THRU-- select s.ID,s.PRODUCT_CODE,n.PAID_THRU NAME_PAID,s.PAID_THRU,s.BILL_THRUFROM Subscriptions s,
NAME n,Member_Types m
WHERE s.ID = n.IDAND n.MEMBER_TYPE = m.MEMBER_TYPEAND n.STATUS = 'A'AND m.MEMBER_RECORD = 1AND s.STATUS LIKE 'A%'AND s.BALANCE = 0AND s.PAID_THRU < s.BILL_THRU
Stored Procedures – Data Integrity(Procedure 3 - Various client scripts)
SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO
CREATE PROCEDURE [dbo].[Proc_niug_clean_up_events]AS
-- Make Sure All Events Have an END_DATE --UPDATE Meet_MasterSET END_DATE = BEGIN_DATE-- select * FROM Meet_MasterWHERE BEGIN_DATE >= Getdate()
AND END_DATE IS NULL
-- Make Sure All Events Have an EARLY and REG_CUTOFF --UPDATE Meet_MasterSET EARLY_CUTOFF = BEGIN_DATE--select * FROM Meet_MasterWHERE BEGIN_DATE >= Getdate()
AND EARLY_CUTOFF IS NULL
UPDATE Meet_MasterSET REG_CUTOFF = BEGIN_DATE--select * FROM Meet_MasterWHERE BEGIN_DATE >= Getdate()
AND REG_CUTOFF IS NULL
UPDATE Meet_MasterSET EARLY_CUTOFF = REG_CUTOFF--select * FROM Meet_MasterWHERE EARLY_CUTOFF > REG_CUTOFF
Stored Procedures – Data Integrity(Procedure 3 - Various client scripts)
-- Make Sure All Events have Web Registrations by Registration Class --UPDATE Meet_MasterSET WEB_REG_CLASS_METHOD = 1-- select * FROM Meet_MasterWHERE BEGIN_DATE >= Getdate()
AND WEB_REG_CLASS_METHOD = 0
-- Make Sure All Functions Have Early and Late Pricing--UPDATE ProductSET PRICE_1 = PRICE_2-- select PRODUCT_CODE, PRICE_1, PRICE_2FROM ProductWHERE PRICE_1 = 0
AND PRICE_2 > 0AND PROD_TYPE = 'MEETING'
UPDATE ProductSET PRICE_3 = PRICE_2-- select PRODUCT_CODE, PRICE_3, PRICE_2FROM ProductWHERE PRICE_3 = 0
AND PRICE_2 > 0AND PROD_TYPE = 'MEETING'
Stored Procedures – Data Integrity(Procedure 4 - Various client scripts)
SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER OFFGO
ALTER PROCEDURE [dbo].[Proc_niug_sync_home_phone]AS
SELECT DISTINCT n.ID,na.PHONE
INTO #homeFROM NAME n,
Name_Address naWHERE n.ID = na.ID
AND na.PURPOSE = 'HOME'AND na.PHONE <> n.HOME_PHONEAND na.PHONE NOT IN ( ' ', NULL )
UPDATE NAMESET HOME_PHONE = h.PHONEFROM NAME n,
#home hWHERE n.ID = h.ID;
DROP TABLE #home
Stored Procedures – Data Integrity(Procedure 5 - Various client scripts)
CREATE PROCEDURE [dbo].[proc_NiUG_reset_BTID_to_Chapter]AS /*===========================================================================================================
=============================STORED PROCEDURE:[dbo].[proc_NiUG_reset_BTID_to_Chapter]
This procedure identifies certain records in the Orders table and updates the BT_IDin the Orders, Trans and Invoice tables that is joined from the Name_Fin table. ======================================================================*/
SET NOCOUNT ONSET XACT_ABORT ON
DECLARE @qty int, @msg varchar(1000)
CREATE TABLE #eligible(ORDER_NUMBER int,ST_ID varchar(10),ORIG_BT_ID varchar(10),NEW_BT_ID varchar(10),INVOICE_REFERENCE_NUM int,MEETCODE varchar(10))
Stored Procedures – Data Integrity(Procedure 5 - Various client scripts)
--grab eligible orders and put in a temp table in case new orders come in whileINSERT INTO #eligible(
ORDER_NUMBER,ST_ID,ORIG_BT_ID, NEW_BT_ID,INVOICE_REFERENCE_NUM,MEETCODE)
SELECT dbo.Orders.ORDER_NUMBER,dbo.Orders.ST_ID,dbo.Orders.BT_ID,dbo.Name_Fin.BT_ID AS NEW_BT_ID,dbo.Orders.INVOICE_REFERENCE_NUM,dbo.Order_Meet.MEETING
FROM dbo.Orders INNER JOINdbo.Order_Meet ON dbo.Orders.ORDER_NUMBER = dbo.Order_Meet.ORDER_NUMBER INNER JOINdbo.Meet_Master ON dbo.Order_Meet.MEETING = dbo.Meet_Master.MEETING LEFT OUTER JOINdbo.Name_Fin ON dbo.Orders.ST_ID = dbo.Name_Fin.ID
WHERE (CONVERT(int, dbo.Orders.ORDER_NUMBER) NOT IN (SELECT DISTINCT CONVERT(int, ORDER_NUMBER) FROM dbo.csys_BTID_RESET_AUDIT) --make sure order hasn't already processed.
AND dbo.Orders.SOURCE_CODE = 'WEB'AND dbo.Meet_Master.[STATUS] = 'A'AND dbo.Orders.INVOICE_REFERENCE_NUM <> 0AND dbo.Name_Fin.BT_ID <> '')OR(CONVERT(int, dbo.Orders.ORDER_NUMBER) NOT IN
(SELECT DISTINCT CONVERT(int, ORDER_NUMBER) FROM dbo.csys_BTID_RESET_AUDIT) --make sure order hasn't already processed.
AND dbo.Orders.SOURCE_CODE = 'WEB'AND dbo.Meet_Master.[STATUS] = 'A'AND dbo.Orders.INVOICE_REFERENCE_NUM <> 0AND dbo.Name_Fin.BT_ID IS NOT NULL )
SELECT @qty = COUNT(*)FROM #eligible
Stored Procedures – Data Integrity(Procedure 5 - Various client scripts)
BEGIN TRANSACTION
--use the temp table to update the actual OrderUPDATE dbo.OrdersSET BT_ID = e.NEW_BT_ID--Select *FROM dbo.Orders INNER JOIN #eligible eON dbo.Orders.ORDER_NUMBER = e.ORDER_NUMBER
IF @@ERROR <> 0 GOTO ABORTTRANS
--use the temp table to update the resulting financial transactionsUPDATE dbo.TransSET BT_ID = e.NEW_BT_ID--Select *FROM dbo.Trans INNER JOIN #eligible eON dbo.Trans.INVOICE_REFERENCE_NUM = e.INVOICE_REFERENCE_NUM
AND dbo.Trans.BT_ID = e.ORIG_BT_ID --make sure the BTIDs are the same, just being anal here
IF @@ERROR <> 0 GOTO ABORTTRANS
--use the temp table to update the overall invoiceUPDATE dbo.InvoiceSET BT_ID = e.NEW_BT_ID--Select *FROM dbo.Invoice INNER JOIN #eligible eON e.INVOICE_REFERENCE_NUM = dbo.Invoice.REFERENCE_NUM
IF @@ERROR <> 0 GOTO ABORTTRANS
Stored Procedures – Data Integrity(Procedure 5 - Various client scripts)
--Put the records affected into my control table so they don't process again.INSERT INTO dbo.csys_BTID_RESET_AUDIT(
ORDER_NUMBER, ST_ID, ORIG_BT_ID, NEW_BT_ID,INVOICE_REFERENCE_NUM,RESET_DATE)
SELECT ORDER_NUMBER, ST_ID, ORIG_BT_ID, NEW_BT_ID,INVOICE_REFERENCE_NUM,getdate()
FROM #eligible
IF @@ERROR <> 0 GOTO ABORTTRANS
COMMIT TRANSACTION
SELECT @msg = CONVERT(varchar,@qty) + ' Records Processed'
PRINT @msg
DROP TABLE #eligible
RETURN
ABORTTRANS:
ROLLBACK TRANSACTION
RAISERROR('Error with proc_reset_BTID_to_Chapter.', 16, 10)
RETURN
GO
Stored Procedures – Data Integrity(Procedure 6 - Various client scripts)
SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO
CREATE procedure [dbo].[proc_CSYS_Invoice_Description]
-- exec proc_csys_invoice_description
AS
/*Rev : 0 Date : March 29, 2012Purpose : To update the Invoice description to equal the Order Lines description line number 1By : Nadine W (C) Systems*/
Update iSet i.Description = ol.DescriptionFrom Orders o Inner Join Order_Lines ol On o.ORDER_NUMBER = ol.ORDER_NUMBERInner Join Invoice i on o.INVOICE_REFERENCE_NUM = i.REFERENCE_NUMWhere ol.LINE_NUMBER = 1and ol.DESCRIPTION <> i.DESCRIPTIONAnd o.SOURCE_SYSTEM in ('AR','ORDER')and o.ORDER_TYPE_CODE = 'Cash'
Stored Procedures – Data Integrity(Procedure 7 - Various client scripts)
-- EMAIL A LIST OF COMMITTEE MEMBERS WHOSE TERMS WILL EXPIRE IN THE NEXT MONTHEXEC msdb.dbo.sp_send_dbmail@profile_name = 'IMIS_Admin',@recipients = '[email protected]',
@copy_recipients='[email protected]',@blind_copy_recipients='[email protected]',@subject = 'COMMITTE MEMBERS WHOSE TERM EXPIRES SOON',@body = 'The following committeee member terms will expire in the next month.',@query = 'SELECT ACTIVITY.ID, NAME.FULL_NAME,ACTIVITY.DESCRIPTION, ACTIVITY.THRU_DATE
FROM NAME INNER JOIN ACTIVITY ON NAME.ID=ACTIVITY.IDWHERE (
ACTIVITY.ACTIVITY_TYPE=''COMMITTEE''AND ACTIVITY.THRU_DATE<=DATEADD (MONTH , 1, DATEADD(DD, DATEDIFF(DD,0,GETDATE()), 0))ANDACTIVITY.THRU_DATE>=GETDATE()
)',@execute_query_database = 'NLNPROD',@query_result_separator = ', ',@query_result_width = 160
Stored Procedures – Data Integrity(Procedure 8- Various client scripts)
-- EMAIL A LIST OF BAD EMAIL ADDRESSESEXEC msdb.dbo.sp_send_dbmail@profile_name = 'IMIS_Admin',@recipients = '[email protected]',
@copy_recipients='[email protected]',@blind_copy_recipients='[email protected]',@subject = 'BAD EMAIL ADDRESSES',@body = 'The following records have bad email addressses.',@query = 'Select Name.ID, Name.Email from name where (email > '' and email not like '%@%')
or (email > '' and email like '%[ ]%')',@execute_query_database = ‘IMISPROD',@query_result_separator = ', ',@query_result_width = 160
Stored Procedures – Data Integrity(Create Stored Procedure In Class)
CREATE FUNCTION vaFixPhone (@sPhone as varchar(25))
--- Returns the phone number in iMIS format if the passed --- phone number is in xxx-xxx-xxxx format------ For example; if 111-222-3333 is passed to this function--- (111) 222-3333 will be returned------ Sample Call:------ SELECT--- work_phone, --- dbo.vaFixPhone(work_phone) as iMIS Format--- FROM--- Name ------\/*--- Sample update call:
UPDATEName SET
WORK_PHONE = dbo.vaFixPhone(WORK_PHONE),FAX = dbo.vaFixPhone(FAX),TOLL_FREE = dbo.vaFixPhone(TOLL_FREE)
*/
RETURNS varchar(25)AS
BEGIN
DECLARE @sRetVal as varchar(25)
Stored Procedures – Data Integrity(Create Stored Procedure In Class)
--- Make sure that phone number fits the format --- of xxx-xxx-xxxxIF Len(@sPhone) = 12 AND SUBSTRING(@sPhone,4,1) = '-' AND SUBSTRING(@sPhone,8,1) = '-'--- Matched - updateSET @sRetVal = '(' + left(@sPhone ,3) + ') ' + Substring(@sPhone,5,3) + '-' + right(@sPhone,4)ELSE--- No match, just return what was passed inSET @sRetVal = @sPhone
RETURN @sRetVal
END
To use:
Create the Function above and then run the following. You can switch to different phone fields in the database including user defined fields for phone numbers where the iMIS phone formatting isn’t automatically applied.
Sample Update Statement:
Update NameSet Work_Phone = dbo.vaFixPhone(WORK_PHONE) Where substring(WORK_PHONE,4,1) = '-'
Stored Procedures – Data Integrity
Lab #4 – Details of requirements for lab exercise will be announced in class.
Stored Procedures and Job Scheduling Do’s and Don’ts
• Always test new stored procedures that updates/inserts data against a current iMIS testdatabase!
• Have others review the results of a new procedure in the test database and receive approval to deploy a new procedure in the production database.
• When creating procedures, always have a section in the procedure that identifies the goal of the procedure, when it was initially deployed, who wrote it (or modified it) and use full names when commenting on who worked on the procedure.
Stored Procedures and Job SchedulingDo’s and Don’ts
• Keep in mind that if you are writing a procedure that affects the Name table, there are triggers on the table that can slow processing down if a large number of records are being acted on.
• If writing a procedure that updates information, make sure that the procedure checks to see if the specific records need updating to begin with. That is, filter out the universe of records that need to be acted on.
Stored Procedures and Job SchedulingDo’s and Don’ts
• When scheduling, have test runs against the test database to get a sense of how long the procedure normally takes to run. Allow for a current gap in the SQL job scheduling to fit the new procedure in.
• Backup! Backup! Backup!
Stored Procedures and Job SchedulingDo’s and Don’ts
/*******************************************************************************
Name: GetJobSchedule
Author: M.PearsonCreation Date: 5 Jun 2002Version: 1.0
Program Overview: This queries the sysjobs, sysjobschedules and sysjobhistory table toproduce a resultset showing the jobs on a server plus their schedules(if applicable) and the maximun duration of the job.
The UNION join is to cater for jobs that have been scheduled but not yetrun, as this information is stored in the 'active_start...' fields of the sysjobschedules table, whereas if the job has already run the schedule information is stored in the 'next_run...' fields of the sysjobschedules table.
Modification History:-------------------------------------------------------------------------------Version Date Name Modification-------------------------------------------------------------------------------1.0 5 Jun 2002 M.Pearson Inital Creation1.1 6 May 2009 A. Gonzalez Adapted to SQL Server 2005 and to show
subday frequencies.
*******************************************************************************/
USE msdbGo
SELECT dbo.sysjobs.Name AS 'Job Name', 'Job Enabled' = CASE dbo.sysjobs.Enabled
WHEN 1 THEN 'Yes'WHEN 0 THEN 'No'
END,
Stored Procedures and Job SchedulingDo’s and Don’ts
'Frequency' = CASE dbo.sysschedules.freq_typeWHEN 1 THEN 'Once'WHEN 4 THEN 'Daily'WHEN 8 THEN 'Weekly'WHEN 16 THEN 'Monthly'WHEN 32 THEN 'Monthly relative'WHEN 64 THEN 'When SQLServer Agent starts'
END, 'Start Date' = CASE active_start_date
WHEN 0 THEN nullELSEsubstring(convert(varchar(15),active_start_date),1,4) + '/' + substring(convert(varchar(15),active_start_date),5,2) + '/' + substring(convert(varchar(15),active_start_date),7,2)
END,'Start Time' = CASE len(active_start_time)
WHEN 1 THEN cast('00:00:0' + right(active_start_time,2) as char(8))WHEN 2 THEN cast('00:00:' + right(active_start_time,2) as char(8))WHEN 3 THEN cast('00:0'
+ Left(right(active_start_time,3),1) +':' + right(active_start_time,2) as char (8))
WHEN 4 THEN cast('00:' + Left(right(active_start_time,4),2) +':' + right(active_start_time,2) as char (8))
WHEN 5 THEN cast('0' + Left(right(active_start_time,5),1) +':' + Left(right(active_start_time,4),2) +':' + right(active_start_time,2) as char (8))
WHEN 6 THEN cast(Left(right(active_start_time,6),2) +':' + Left(right(active_start_time,4),2) +':' + right(active_start_time,2) as char (8))
END,-- active_start_time as 'Start Time',
CASE len(run_duration)WHEN 1 THEN cast('00:00:0'
+ cast(run_duration as char) as char (8))WHEN 2 THEN cast('00:00:‘
Stored Procedures and Job SchedulingDo’s and Don’ts
+ cast(run_duration as char) as char (8))WHEN 3 THEN cast('00:0'
+ Left(right(run_duration,3),1) +':' + right(run_duration,2) as char (8))
WHEN 4 THEN cast('00:' + Left(right(run_duration,4),2) +':' + right(run_duration,2) as char (8))
WHEN 5 THEN cast('0' + Left(right(run_duration,5),1) +':' + Left(right(run_duration,4),2) +':' + right(run_duration,2) as char (8))
WHEN 6 THEN cast(Left(right(run_duration,6),2) +':' + Left(right(run_duration,4),2) +':' + right(run_duration,2) as char (8))
END as 'Max Duration',CASE(dbo.sysschedules.freq_subday_interval)
WHEN 0 THEN 'Once'ELSE cast('Every '
+ right(dbo.sysschedules.freq_subday_interval,2) + ' '+ CASE(dbo.sysschedules.freq_subday_type)
WHEN 1 THEN 'Once'WHEN 4 THEN 'Minutes'WHEN 8 THEN 'Hours'
END as char(16))END as 'Subday Frequency'
FROM dbo.sysjobsLEFT OUTER JOIN dbo.sysjobschedulesON dbo.sysjobs.job_id = dbo.sysjobschedules.job_idINNER JOIN dbo.sysschedules ON dbo.sysjobschedules.schedule_id = dbo.sysschedules.schedule_idLEFT OUTER JOIN (SELECT job_id, max(run_duration) AS run_duration
FROM dbo.sysjobhistoryGROUP BY job_id) Q1
ON dbo.sysjobs.job_id = Q1.job_idWHERE Next_run_time = 0
UNION
Stored Procedures and Job SchedulingDo’s and Don’ts
SELECT dbo.sysjobs.Name AS 'Job Name', 'Job Enabled' = CASE dbo.sysjobs.Enabled
WHEN 1 THEN 'Yes'WHEN 0 THEN 'No'
END,'Frequency' = CASE dbo.sysschedules.freq_type
WHEN 1 THEN 'Once'WHEN 4 THEN 'Daily'WHEN 8 THEN 'Weekly'WHEN 16 THEN 'Monthly'WHEN 32 THEN 'Monthly relative'WHEN 64 THEN 'When SQLServer Agent starts'
END, 'Start Date' = CASE next_run_date
WHEN 0 THEN nullELSEsubstring(convert(varchar(15),next_run_date),1,4) + '/' + substring(convert(varchar(15),next_run_date),5,2) + '/' + substring(convert(varchar(15),next_run_date),7,2)
END,'Start Time' = CASE len(next_run_time)
WHEN 1 THEN cast('00:00:0' + right(next_run_time,2) as char(8))WHEN 2 THEN cast('00:00:' + right(next_run_time,2) as char(8))WHEN 3 THEN cast('00:0'
+ Left(right(next_run_time,3),1) +':' + right(next_run_time,2) as char (8))
WHEN 4 THEN cast('00:' + Left(right(next_run_time,4),2) +':' + right(next_run_time,2) as char (8))
WHEN 5 THEN cast('0' + Left(right(next_run_time,5),1) +':' + Left(right(next_run_time,4),2) +':' + right(next_run_time,2) as char (8))
WHEN 6 THEN cast(Left(right(next_run_time,6),2) +':' + Left(right(next_run_time,4),2) +':' + right(next_run_time,2) as char (8))
END,
Stored Procedures and Job SchedulingDo’s and Don’ts
-- next_run_time as 'Start Time',CASE len(run_duration)
WHEN 1 THEN cast('00:00:0'+ cast(run_duration as char) as char (8))
WHEN 2 THEN cast('00:00:'+ cast(run_duration as char) as char (8))
WHEN 3 THEN cast('00:0' + Left(right(run_duration,3),1) +':' + right(run_duration,2) as char (8))
WHEN 4 THEN cast('00:' + Left(right(run_duration,4),2) +':' + right(run_duration,2) as char (8))
WHEN 5 THEN cast('0' + Left(right(run_duration,5),1) +':' + Left(right(run_duration,4),2) +':' + right(run_duration,2) as char (8))
WHEN 6 THEN cast(Left(right(run_duration,6),2) +':' + Left(right(run_duration,4),2) +':' + right(run_duration,2) as char (8))
END as 'Max Duration',CASE(dbo.sysschedules.freq_subday_interval)
WHEN 0 THEN 'Once'ELSE cast('Every '
+ right(dbo.sysschedules.freq_subday_interval,2) + ' '+ CASE(dbo.sysschedules.freq_subday_type)
WHEN 1 THEN 'Once'WHEN 4 THEN 'Minutes'WHEN 8 THEN 'Hours'
END as char(16))END as 'Subday Frequency‘
Stored Procedures and Job SchedulingDo’s and Don’ts
FROM dbo.sysjobsLEFT OUTER JOIN dbo.sysjobschedules ON dbo.sysjobs.job_id = dbo.sysjobschedules.job_idINNER JOIN dbo.sysschedules ON dbo.sysjobschedules.schedule_id = dbo.sysschedules.schedule_idLEFT OUTER JOIN (SELECT job_id, max(run_duration) AS run_duration
FROM dbo.sysjobhistoryGROUP BY job_id) Q1
ON dbo.sysjobs.job_id = Q1.job_idWHERE Next_run_time <> 0
ORDER BY [Start Date],[Start Time]
Useful SQL Scripts To Manage / Troubleshoot iMIS
The following SQL Scripts are ones that can be used to help troubleshoot issues with iMIS either on a SQL Server level or reviewing data in the database.
The iMIS Community (www.imiscommunity.com) is a great source for locating these types of scripts!
Useful SQL Scripts To Manage / Troubleshoot iMIS
Find Blocking Process
SELECTspid,sp.STATUS,loginame = SUBSTRING(loginame, 1, 12),hostname = SUBSTRING(hostname, 1, 12),blk = CONVERT(CHAR(3), blocked),open_tran,dbname = SUBSTRING(DB_NAME(sp.dbid),1,10),cmd,waittype,waittime,last_batch,SQLStatement =
SUBSTRING(
qt.text,er.statement_start_offset/2,(CASE WHEN er.statement_end_offset = -1
THEN LEN(CONVERT(nvarchar(MAX), qt.text)) * 2ELSE er.statement_end_offsetEND - er.statement_start_offset)/2
)FROM master.dbo.sysprocesses spLEFT JOIN sys.dm_exec_requests er
ON er.session_id = sp.spidOUTER APPLY sys.dm_exec_sql_text(er.sql_handle) AS qtWHERE spid IN (SELECT blocked FROM master.dbo.sysprocesses)AND blocked = 0
Useful SQL Scripts To Manage / Troubleshoot iMIS
Find Indexes Fragmented Above 30 Percent (can adjust the percentage)
SELECT OBJECT_NAME(ind.OBJECT_ID) AS TableName,ind.name AS IndexName, indexstats.index_type_desc AS IndexType,indexstats.avg_fragmentation_in_percentFROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstatsINNER JOIN sys.indexes indON ind.object_id = indexstats.object_idAND ind.index_id = indexstats.index_idWHERE indexstats.avg_fragmentation_in_percent > 30ORDER BY indexstats.avg_fragmentation_in_percent DESC
Useful SQL Scripts To Manage / Troubleshoot iMIS
Find Objects Where A Table Name Is Referenced:
SELECT DISTINCT so.name,so.xtype as ObjectTypeFROM syscomments scINNER JOIN sysobjects so ON sc.id=so.idWHERE sc.TEXT LIKE '%Name_Address%’
Object Types:
AP: applicationC : check cnsD : default (maybe cns)EN: event notificationF : foreign key cnsFN: scalar functionFS: assembly scalar functionFT: assembly table functionIF: inline functionIS: inline scalar functionIT: internal tableL : logP : stored procedurePC : assembly stored procedurePK: primary key cnsR : ruleRF: replication filter procS : system tableSN: synonymSQ: queueTA: assembly triggerTF: table functionTR: triggerU : user tableUQ: unique key cnsV : viewX : extended stored proc
Useful SQL Scripts To Manage / Troubleshoot iMIS
Find Triggers In the Database:
SELECT sysobjects.name AS trigger_name
,USER_NAME(sysobjects.uid) AS trigger_owner,s.name AS table_schema,OBJECT_NAME(parent_obj) AS table_name,OBJECTPROPERTY( id, 'ExecIsUpdateTrigger') AS isupdate,OBJECTPROPERTY( id, 'ExecIsDeleteTrigger') AS isdelete,OBJECTPROPERTY( id, 'ExecIsInsertTrigger') AS isinsert,OBJECTPROPERTY( id, 'ExecIsAfterTrigger') AS isafter,OBJECTPROPERTY( id, 'ExecIsInsteadOfTrigger') AS isinsteadof,OBJECTPROPERTY(id, 'ExecIsTriggerDisabled') AS [disabled]
FROM sysobjects/*INNER JOIN sysusers
ON sysobjects.uid = sysusers.uid */ INNER JOIN sys.tables t
ON sysobjects.parent_obj = t.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE sysobjects.type = 'TR'Order by OBJECT_NAME(parent_obj)
Useful SQL Scripts To Manage / Troubleshoot iMIS
Find Contact Information By ID:
-- look up Contact information based on ID-- edit the value for @theID below and execute the script
DECLARE @theID VARCHAR(10)SET @theID = '217'
SELECT '' AS 'Name table', *FROM Name WHERE ID = @theID
-- a missing row here can break many things because it's frequently INNER JOINed with NameSELECT '' AS 'Name_Fin table', *FROM Name_Fin WHERE ID = @theID
SELECT '' AS 'Name_Security table', *FROM Name_Security WHERE ID = @theID
-- a missing row here can break many things because it's frequently INNER JOINed with NameSELECT '' AS 'Name_Security_Groups table', *FROM Name_Security_GroupsWHERE ID = @theID
SELECT '' AS 'Users table', *FROM UsersWHERE UserId IN
(SELECT UserId FROM UserMain WHERE UserKey IN(SELECT ContactKey FROM ContactMain WHERE SyncContactID IN(SELECT ID FROM Name WHERE ID = @theID)))
SELECT '' AS 'ContactMain table', *FROM ContactMainWHERE SyncContactID = @theID
Useful SQL Scripts To Manage / Troubleshoot iMIS
SELECT '' AS 'UserMain table', *FROM UserMainWHERE UserKey IN
(SELECT ContactKey FROM ContactMain WHERE SyncContactID IN(SELECT ID FROM Name WHERE ID = @theID))
SELECT '' AS 'aspnet_Users table', *FROM aspnet_UsersWHERE UserId IN(SELECT ProviderKey FROM UserMain WHERE UserKey IN(SELECT ContactKey FROM ContactMain WHERE SyncContactID IN(SELECT ID FROM Name WHERE ID = @theID)))
SELECT '' AS 'aspnet_Membership table', *FROM aspnet_MembershipWHERE UserId IN(SELECT ProviderKey FROM UserMain WHERE UserKey IN
(SELECT ContactKey FROM ContactMain WHERE SyncContactID IN(SELECT ID FROM Name WHERE ID = @theID)))
SELECT '' AS 'Individual table', *FROM IndividualWHERE ContactKey IN
(SELECT ContactKey FROM ContactMain WHERE SyncContactID IN(SELECT ID FROM Name WHERE ID = @theID))
SELECT '' AS 'Institute table', *FROM InstituteWHERE ContactKey IN
(SELECT ContactKey FROM ContactMain WHERE SyncContactID IN(SELECT ID FROM Name WHERE ID = @theID))
Useful SQL Scripts To Manage / Troubleshoot iMIS
Find Contact Information By UserID:
--Contact Info by UserID-- look up Contact information based on UserID-- edit the value for @theUserID below and execute the script
DECLARE @theUserID VARCHAR(60)DECLARE @theID VARCHAR(10)SET @theUserID = 'GUEST'
-- two different ways to get from UserID to Name.IDSELECT @theID = ID FROM Name_Security WHERE LOWER(WEB_LOGIN) = LOWER(@theUserID)IF (@theID IS NULL) SELECT @theID = ContactMaster FROM UserMain WHERE LOWER(UserId) = LOWER(@theUserID)
SELECT '' AS 'UserMain table', * FROM UserMainWHERE UserId = @theUserID
SELECT '' AS 'Users table', * FROM Users WHERE UserId = @theUserID
SELECT '' AS 'aspnet_Users table', * FROM aspnet_UsersWHERE LOWER(UserName) = LOWER(@theUserID)
SELECT '' AS 'aspnet_Membership table', * FROM aspnet_MembershipWHERE UserId = (SELECT UserId FROM aspnet_Users WHERE LOWER(UserName) = LOWER(@theUserID))
SELECT '' AS 'Name table', * FROM Name WHERE ID = @theID
-- a missing row here can break many things because it's frequently INNER JOINed with NameSELECT '' AS 'Name_Fin table', * FROM Name_FinWHERE ID = @theID
SELECT '' AS 'Name_Security table', * FROM Name_SecurityWHERE ID = @theID
-- a missing row here can break many things because it's frequently INNER JOINed with NameSELECT '' AS 'Name_Security_Groups table', * FROM Name_Security_GroupsWHERE ID = @theID
SELECT '' AS 'ContactMain table', * FROM ContactMainWHERE SyncContactID = @theID
SELECT '' AS 'Individual table', * FROM Individual WHERE ContactKey IN (SELECT ContactKey FROM ContactMain WHERE SyncContactID = @theID)
SELECT '' AS 'Institute table', * FROM Institute WHERE ContactKey IN (SELECT ContactKey FROM ContactMain WHERE SyncContactID = @theID)
Useful SQL Scripts To Manage / Troubleshoot iMIS