Simple Programming Part 1 SECTION 7 Procedures and Functions.
-
Upload
dominic-franklin -
Category
Documents
-
view
229 -
download
0
Transcript of Simple Programming Part 1 SECTION 7 Procedures and Functions.
Introduction
• SQL is only a query language
• T-SQL (SQL) does not have features that allow sophisticated computations
• Microsoft SQL solution• T-SQL Procedures and Functions
• Looking at basics
• Users need more sophisticated SQL-oriented programming capabilities
Stored Procedures and Functions
• Lets you use all the SQL data manipulations
• Fully SQL data types
• Allows you to do sophisticated processing
The Front End
• Lets you create SQL data manipulations
• Also lets you do programming
• The usual front-end displayed to the user
Stored Procedures
• Stored in the database
• A stored procedure is a group of Transact-SQL statements compiled into a single execution plan.
IF (@QuantityOrdered < (SELECT QuantityOnHand
FROM Inventory
WHERE PartID = @PartOrdered) )
BEGIN
-- SQL statements to update tables and process order.
END
ELSE
BEGIN
-- SELECT statement to retrieve the IDs of alternate items
-- to suggest as replacements to the customer.
END
A Generic Example
Stored Functions
• A function is designed to return a value used within a larger SQL statemen
• Functions cannot be used to make changes to the database, whereas stored procedures allow you to do inserts and updates, etc.
Basic Procedure Structure
• Four sections– Header section (optional)– Declaration section (optional)– Execution section– Exception section (optional)
Header Section
• Anonymous block header
• The specification of the function-- ==================
-- Author
-- Create date:
-- Description
-- ==================
• Block labels make it easier to read codes
Declaration Section (Optional)
• Ends at keyword – BEGIN
• Starts with keyword– DECLARE
• Contains declarations for• Variables, constants, cursors, exceptions
• What are we doing here?
• When a procedure has finished executing– Declarations stop existing
DECLARE @num_a NUMERIC = 6,@num_b NUMERIC;
In our example:
BEGIN try
-- Generate a divide-by-zero error.
SET @num_b = 0;
SET @num_a = @num_a / @num_b;
PRINT @num_a;
END try
BEGIN catch
SELECT ERROR_MESSAGE() AS ErrorMessage;
END catch
The TRY statement lets you test a block of code for errors
The CATCH statement lets you handle the error
Creating a Simple Procedure
Create procedure test_procasSelect * from customer;
• We will try the following code
• Use
• CREATE procedure_name
• AS procedure_body
CREATE PROCEDURE test_procASDECLARE @alpha nVARCHAR(30)BEGINSET @alpha = ‘HELLO WORLD’PRINT @alphaEND
Calling Procedures or Functions
Without any parameters
Execute procedure_name;
With formal parameters
Execute procedure_name @alpha = 50, @bravo = 20;
• A procedure or function may not have formal parameters or default values
Variables
• Storing numbers– NUMERIC datatype
• Storing text– CHAR, VARCHAR, nVARCHAR datatypes
• Variables:• Essentially containers with name tags
Unicode Characters• Unicode is a computing industry standard for the consistent encoding,
representation and handling of text expressed in most of the world's writing systems.
• Unicode's success at unifying character sets has led to its widespread and predominant use in the internationalization of computer software.
• nVARCHAR
• All modern operating systems and development platforms use Unicode internally.
Declaring Variables
• A valid variable_name
– Up to 30 characters
– Letters, 0-9, underscore(_), $, and #
– Starts with @
– Cannot use a reserved word that is used by the DBMS
• The syntax@variable_name datatype or
@variable_name (datatype) = default_value_expression
e.g. @num_b NUMERIC or
@num_a NUMERIC = 6
@num_c NUMERIC(4,2)
CREATE PROCEDURE increase_prices @old_price NUMERIC, @percent_increase NUMERIC = 5ASDECLARE@new_price NUMERICBEGINSET @new_price = @old_price + @old_price * @percent_increase/100PRINT 'New Price: $' + CAST(@new_price as nVARCHAR)END
A Simple Procedure – calculates a percent price increase
CREATE PROCEDURE increase_prices @old_price NUMERIC, @percent_increase NUMERIC = 5AS
DECLARE@new_price NUMERICBEGINSET @new_price = @old_price + @old_price * @percent_increase/100PRINT 'New Price: $' + CAST(@new_price as nVARCHAR)END
CASTThe PRINT will print a numeric by itself if there are no other items to be printed. If there are two or more data types that are numeric you must use CAST or CONVERT. @new_price is numeric. Therefore CAST converts @new_price to a nvarchar datatype.
Control Structures
• One can do conditional processing
• Also can do iterations
• Many times you may want to do one thing if something is true or something else if it is not true
IF Statement
• The syntax:
IF condition_1
BEGIN (SET) Actions_1 END
ELSE IF condition_2
BEGIN (SET) Actions_2 END
……..
ELSE
BEGIN (SET) Actions_last END
Zodiac Sign
YEAR OF BIRTH
Rat 2008 1996 1984 1972 1960 1948 1936 1924 1912 1900
Bull 2009 1997 1985 1973 1961 1949 1937 1925 1913 1901
Tiger 2010 1998 1986 1974 1962 1950 1938 1926 1914 1902
Rabbit 2011 1999 1987 1975 1963 1951 1939 1927 1915 1903
Dragon 2012 2000 1988 1976 1964 1952 1940 1928 1916 1904
Snake 2013 2001 1989 1977 1965 1953 1941 1929 1917 1905
Horse 2014 2002 1990 1978 1966 1954 1942 1930 1918 1906
Goat 2015 2003 1991 1979 1967 1955 1943 1931 1919 1907
Monkey 2016 2004 1992 1980 1968 1956 1944 1932 1920 1908
Rooster 2017 2005 1993 1981 1969 1957 1945 1933 1921 1909
Dog 2018 2006 1994 1982 1970 1958 1946 1934 1922 1910
Pig 2019 2007 1994 1983 1971 1959 1947 1935 1923 1911
• Want to develop a procedure to calculate your Chinese birth sign.
Create procedure CZP @birthyear numeric
AS
IF @birthyear IN(1900,1912,1924,1936,1948,1960,1972,1984,1996,2008)
BEGIN
PRINT 'You are a rat'
END
ELSE
BEGIN
PRINT 'You are not a rat'
END
CREATE PROCEDURE Chinese_Zodiac_Proc (@BirthDate NUMERIC)--This procedure deals with birth years and the Chinese ZodiacASPRINT ('*****');IF @BirthDate IN( 1924, 1936, 1948, 1960, 1972, 1984, 1996)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Rat.') ENDELSE IF @BirthDate IN( 1925, 1937, 1949, 1961, 1973, 1985, 1997)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Bull.') ENDELSE IF @BirthDate IN( 1926, 1938, 1950, 1962, 1974, 1986, 1998)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Tiger.') ENDELSE IF @BirthDate IN( 1927, 1939, 1951, 1963, 1975, 1987, 1999)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Rabbit.') ENDELSE IF @BirthDate IN( 1928, 1940, 1952, 1964, 1976, 1988, 2000)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Dragon.') ENDELSE IF @BirthDate IN( 1929, 1941, 1953, 1965, 1977, 1989, 2001)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Snake.') ENDELSE IF @BirthDate IN( 1930, 1942, 1954, 1966, 1978, 1990, 2002)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Horse.') ENDELSE IF @BirthDate IN( 1931, 1943, 1955, 1967, 1979, 1991, 2003)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Sheep.') ENDELSE IF @BirthDate IN( 1932, 1944, 1956, 1968, 1980, 1992, 2004)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Monkey.') ENDELSE IF @BirthDate IN( 1933, 1945, 1957, 1969, 1981, 1993, 2005)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Rooster.') ENDELSE IF @BirthDate IN( 1934, 1946, 1958, 1970, 1982, 1994, 2006)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Dog.') ENDELSE IF @BirthDate IN( 1935, 1947, 1959, 1971, 1983, 1995, 2007)BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @BirthDate) + ', the year of the Pig.') ENDELSEBEGIN PRINT (' Your birth date is out of the program range!') ENDPRINT ('*****')
Now to develop the procedure using a calculation for birth sign
1944/12 = 162.00 MONKEY1945/12 = 162.083333 ROOSTER1946/12 = 162.166667 DOG1947/12 = 162.25 PIG1948/12 = 162.33333 RAT1949/12 = 162.416667 BULL1950/12 = 162.5 TIGER1951.12 = 162.583333 RABBIT1952/12 = 162.666667 DRAGON1953/12 = 162.75 SNAKE1954/12 = 162.833333 HORSE1955/12 = 162.916667 SHEEP1956/12 = 163.00 MONKEY
Therefore:
Sign Remainder (R) R x 12
MONKEY 0 0
ROOSTER 0.083333 1
DOG 0.166667 2
PIG 0.25 3
RAT 0.33333 4
BULL 0.416667 5
TIGER 0.5 6
RABBIT 0.583333 7
DRAGON 0.666667 8
SNAKE 0.75 9
HORSE 0.833333 10
SHEEP 0.916667 11
Thus have to calculate the remainder for each birth year
Use @birthyear = 1950
Declare three variables:@X NUMERIC(10,6)@Y NUMERIC(4)@Z NUMERIC(3,2)
Now SET @X =@birthyear/12 (162.5)SET @Y = @birthyear/12 (162)
SET @Z = @X - @Y (0.50)
CREATE PROCEDURE Chinese_Zodiac_Proc02 (@birthyear NUMERIC)--This procedure deals with birth years and the Chinese ZodiacASDECLARE@X NUMERIC(10,6), @Y NUMERIC(4), @Z NUMERIC(2)SET @X = @birthyear/12SET @Y = @birthyear/12BEGINIF @Y > @X SET @Y = @Y-1SET @Z = (@X - @Y)*12ENDPRINT ('*****');IF @Z = 0BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Monkey.') ENDELSE IF @Z = 1BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Rooster.') ENDELSE IF @Z = 2BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Dog.') ENDELSE IF @Z = 3BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Pig.') ENDELSE IF @Z = 4BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Rat.') ENDELSE IF @Z = 5BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Bull.') ENDELSE IF @Z = 6BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Tiger.') ENDELSE IF @Z = 7BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Rabbit.') ENDELSE IF @Z = 8BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Dragon.') ENDELSE IF @Z = 9BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Snake.') ENDELSE IF @Z = 10BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Horse.') ENDELSE IF @Z = 11BEGIN PRINT ('You were born in ' + CONVERT(nVARCHAR(20), @birthyear) + ', the year of the Sheep.') ENDPRINT ('*****')
No correction if @Y > @X
Correction if @Y > @X
@Z is negative @Z is positive
How can @Y be greater than @X?
There is a problem with BCE year as there is no year zero.
If the procedure uses ‘0’, the answer is:
****You were born in 0, the year of the Monkey****
This is incorrect as 1 BCE is the year of the Monkey
This is corrected in the next slide
WHILE LOOP
• An iteration construct
• The Syntax:
Declare @counter intSet @counter = 1While @counter < 10Begin print 'The counter is ' + cast(@counter as nvarchar) Set @counter = @counter + 1End
OR:
Declare @counter int = 1While @counter < 10Begin print 'The counter is ' + cast(@counter as nvarchar) Set @counter = @counter + 1End
• Will use the following table:1. For another loop example; and
2. For a discussion with CURSORS.
CREATE TABLE CHINESE_ZODIAC(Number NUMERIC(2) CONSTRAINT cz_pk PRIMARY KEY, ZodiacSign nVARCHAR(10))
INSERT INTO CHINESE_ZODIAC VALUES (0,'Monkey')INSERT INTO CHINESE_ZODIAC VALUES (1,'Rooster')INSERT INTO CHINESE_ZODIAC VALUES (2,'Dog')INSERT INTO CHINESE_ZODIAC VALUES (3,'Pig')INSERT INTO CHINESE_ZODIAC VALUES (4,'Rat')INSERT INTO CHINESE_ZODIAC VALUES (5,'Bull')INSERT INTO CHINESE_ZODIAC VALUES (6,'Tiger')INSERT INTO CHINESE_ZODIAC VALUES (7,'Rabbit')INSERT INTO CHINESE_ZODIAC VALUES (8,'Dragon')INSERT INTO CHINESE_ZODIAC VALUES (9,'Snake')INSERT INTO CHINESE_ZODIAC VALUES (10,'Horse')INSERT INTO CHINESE_ZODIAC VALUES (11,'Goat')
Declare @counter intSet @counter = 0While @counter < 7Begin Select * from Chinese_Zodiac where rounding = @counter Set @counter = @counter + 1End
Simple example of using a While Loop
GOTO LOOP
• Once again an iteration construct
• The Syntax:
DECLARE @counter INTEGER = 0EPSILON:BEGINPRINT 'Hello World'SET @counter = @counter + 1ENDIF @Counter < 11 GOTO EPSILON
According to Microsoft:
Use GOTO statement sparingly. Excessive use of the GOTO statement adds difficult to understand the logic of the T-SQL batch. You can almost always implement the logic using other control-of-flow statements.
According to Wikipedia:
Spaghetti code is a derogatory term for source code that has a complex and tangled control structure, especially one using many GOTO statements, exceptions, threads, or other unstructured branching constructs. It is named such because program flow is conceptually like a bowl of spaghetti, i.e. twisted and tangled. Spaghetti code can be caused by several factors, such as continuous modifications by several people over a long life cycle. Structured programming greatly decreases the incidence of spaghetti code.
Problems with GOTO
• An example. Create a function that:
• Compute discounts on orders
• Input order amounts
• Returns discount amount
(zero for wrong inputs)
• The RETURN keyword
FUNCTIONS