CIS 612 Lab Assignment 2cis.csuohio.edu/~sschung/cis612/Lab2_SolutionAnkur.pdf · CIS 612 Lab...
Transcript of CIS 612 Lab Assignment 2cis.csuohio.edu/~sschung/cis612/Lab2_SolutionAnkur.pdf · CIS 612 Lab...
CIS 612 Lab Assignment 2
Subject: Modern Database Programming and Big Data Processing
Instructor: Dr. Sunnie S. Chung
Software’s Used:
• Microsoft SQL Server 2012
• SQL Server Management Studio
• Microsoft Visual Studio 2012
Subject: Using UDT, UDF and Table Function
Part 1:
1. Creating User Defined Type GeoPoint, Table Functions Dept_GeoLocations
using System;
using System.Data;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server; using System.Text;
using System.Collections.Generic;
using System.Linq; using System.Threading.Tasks;
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)]
public struct PointType : INullable
{ private bool is_null;
private int _x;
private int _y; public bool IsNull
{
get {
return (is_null);
} }
public static PointType Null
{ get
{
PointType pt = new PointType(); pt.is_null = true;
return pt;
} }
public override string ToString()
{ return _x + ":" + _y;
}
[SqlMethod(OnNullCall = false)]
public static PointType Parse(SqlString s)
{
if (s.IsNull) return Null;
PointType pt = new PointType();
string[] xy = s.Value.Split(":".ToCharArray()); pt.X = Int32.Parse(xy[0]);
pt.Y = Int32.Parse(xy[1]);
return pt;
}
public int X
{ get
{
return this._x;
} set
{
int temp = _x; _x = value;
}
}
public int Y
{
get {
return this._y;
} set
{
int temp = _y; _y = value;
}
} }
Test Script 1:
USE GeoLocationNew
DROP TABLE TablePoints CREATE TABLE dbo.TablePoints (
ID int IDENTITY(1,1) PRIMARY KEY,
Pnt PointType) INSERT INTO dbo.TablePoints (Pnt) VALUES (CONVERT(PointType, '3:4'))
INSERT INTO dbo.TablePoints (Pnt) VALUES (CONVERT(PointType, '-1:5'))
INSERT INTO dbo.TablePoints (Pnt) VALUES (CAST ('1:99' AS PointType))
SELECT ID, Pnt.ToString() as StringPoint,
Pnt.X as X,
Pnt.Y as Y FROM dbo.TablePoints
Output:
Test Script 2:
CREATE TABLE Locations (grid_location dbo.PointType) INSERT INTO Locations (grid_location) VALUES ('3:2') INSERT INTO Locations (grid_location) VALUES ('-1:1') INSERT INTO Locations (grid_location) VALUES ('-1:-1') INSERT INTO Locations (grid_location) VALUES ('-8:-9') INSERT INTO Locations (grid_location) VALUES ('4:-9') ------------------------------------------------------------------- -- -- view the data -- ------------------------------------------------------------------- SELECT * FROM dbo.Locations SELECT grid_location.X AS "X", grid_location.Y AS "Y", grid_location.ToString() AS "Point" FROM Locations ------------------------------------------------------------------- -- -- update some rows -------------------------------------------------------------------- UPDATE dbo.Locations SET grid_location.X = 5 WHERE grid_location.Y < 0 SELECT grid_location.X AS "X", grid_location.Y AS "Y", grid_location.ToString() AS "Point" FROM Locations;
Output:
2. Create Table Function that returns a table Dept_GeoLocations:
Table Function:
using System;
using System.Linq; using System.Text;
using System.Threading.Tasks;
using System.Collections; using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public class GeoLocation
{ public SqlInt32 Dnumber;
public SqlString Dlocation;
public SqlString Location;
public GeoLocation(SqlInt32 Dnum, SqlString Dloc, SqlString Geoloc)
{ Dnumber = Dnum;
Dlocation = Dloc;
Location = Geoloc;
}
[SqlFunction(
DataAccess = DataAccessKind.Read, FillRowMethodName = "FillRow",
TableDefinition = "(Dnumber int, Dlocation varchar(15), Geolocation
nvarchar")] public static IEnumerable InitMethod()
{
ArrayList resultCollection = new ArrayList();
using (SqlConnection connection = new SqlConnection("context
connection=true"))
{ connection.Open();
using (SqlCommand selectDepartment = new SqlCommand( "SELECT *" +
"FROM [Company].[dbo].[DEPT_LOCATIONS] ",
connection)) {
using (SqlDataReader department_record =
selectDepartment.ExecuteReader()) {
while (department_record.Read())
{ SqlString emailAddress =
department_record.GetSqlString(1);
resultCollection.Add(new GeoLocation( department_record.GetSqlInt32(0),
department_record.GetSqlString(1),
DepartmentLocation.getDepartmentLocation(department_record.GetSqlInt32(0), department_record.GetSqlString(1))
));
} }
}
}
return resultCollection;
}
public static void FillRow(
object emailResultObj,
out SqlInt32 Dnumber, out SqlString Dlocation,
out SqlString GeoLocation)
{
GeoLocation deptResult = (GeoLocation)emailResultObj;
Dnumber = deptResult.Dnumber;
Dlocation = deptResult.Dlocation; GeoLocation = deptResult.Location;
}
}
Scalar Function:
using System;
using System.Collections.Generic; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Data.SqlTypes;
public class DepartmentLocation
{
public static SqlString getDepartmentLocation(SqlInt32 departmentID, SqlString dloc)
{
PointType location = new PointType(); String departmentPK = departmentID +""+ (String)dloc;
switch(departmentPK)
{ case "1Houston":
location.X = 3;
location.Y = 2; break;
case "4Stafford":
location.X = -1;
location.Y = 1; break;
case "5Bellaire":
location.X = -1; location.Y = -1;
break;
case "5Sugarland": location.X = -8;
location.Y = -9;
break;
case "5Houston": location.X = 4;
location.Y = -9;
break; }
return location.ToString(); }
}
Test Script:
SELECT * FROM Dept_GeoLocation
Output:
Part 2:
1. Write a Table Function TF_Total_Salary_By_Dept that returns a table
Tab_TotalSalaryByDept with five column info as follows :
Tab_TotalSalaryByDept(
Dept_No INT,
Dept_Name VarChar(30),
COUNT_Emp INT,
SUM_Salary INT,
AVE_Salary INT
)
Table Function:
USE [Company]
GO CREATE FUNCTION TF_Total_Salary_By_Dept()
RETURNS @Tab_TotalSalaryByDept TABLE (
Dept_No INT,
Dept_Name VarChar(30), COUNT_Emp INT,
SUM_Salary INT,
AVE_Salary INT )
AS
BEGIN INSERT INTO @Tab_TotalSalaryByDept(Dept_No, Dept_Name, COUNT_Emp,
SUM_Salary, AVE_Salary)
SELECT DEPARTMENT.Dnumber,DEPARTMENT.Dname,COUNT(EMPLOYEE.Dno) AS
COUNT_Emp ,SUM(EMPLOYEE.Salary) AS SUM_Salary, AVG(EMPLOYEE.Salary) AS AVE_salary FROM DEPARTMENT
INNER JOIN EMPLOYEE
ON DEPARTMENT.Dnumber = EMPLOYEE.Dno GROUP BY DEPARTMENT.Dnumber,DEPARTMENT.Dname;
RETURN;
END;
Screenshot:
2. Write a Stored Procedure SP_New_Total_Salary_By_Dept using(by
calling) the Table Function TF_Total_Salary_By_Dept that you created in
1.
USE [Company]
GO DROP PROCEDURE SP_New_Total_Salary_By_Dept
GO
CREATE PROCEDURE SP_New_Total_Salary_By_Dept AS
CREATE TABLE NEWTab_TotalSalaryByDept
(
Dept_No INT, Dept_Name VarChar(30),
COUNT_Emp INT,
SUM_Salary INT, AVE_Salary INT,
New_SUM_Salary INT,
New_Ave_Salary INT )
IF EXISTS(SELECT * FROM TF_Total_Salary_By_Dept()) BEGIN
DECLARE @Dept_No INT,
@Dept_Name VarChar(30),
@COUNT_Emp INT, @SUM_Salary INT,
@AVE_Salary INT,
@New_SUM_Salary INT, @New_AVE_Salary INT
DECLARE SalaryDept CURSOR
LOCAL SCROLL STATIC
FOR
SELECT * FROM TF_Total_Salary_By_Dept() tf
OPEN SalaryDept
FETCH NEXT FROM SalaryDept INTO @Dept_No, @Dept_Name, @COUNT_Emp, @SUM_Salary, @AVE_Salary
WHILE @@FETCH_STATUS = 0
BEGIN --Rise by 10%
if(@Dept_No = 1)
BEGIN SELECT @New_SUM_Salary = @SUM_Salary + (0.1 *
@SUM_Salary)
SELECT @New_AVE_Salary =
@New_SUM_Salary/@COUNT_Emp END
--Rise by 20%
else if(@Dept_No = 4) BEGIN
SELECT @New_SUM_Salary = @SUM_Salary + (0.2 *
@SUM_Salary) SELECT @New_AVE_Salary =
@New_SUM_Salary/@COUNT_Emp
END
--Rise by 30% else if(@Dept_No = 5)
BEGIN
SELECT @New_SUM_Salary = @SUM_Salary + (0.3 * @SUM_Salary)
SELECT @New_AVE_Salary =
@New_SUM_Salary/@COUNT_Emp
END --Rise by 40%
else if(@Dept_No = 7)
BEGIN SELECT @New_SUM_Salary = @SUM_Salary + (0.4 *
@SUM_Salary)
SELECT @New_AVE_Salary = @New_SUM_Salary/@COUNT_Emp
END
INSERT INTO NEWTab_TotalSalaryByDept
VALUES(@Dept_No,@Dept_Name,@COUNT_Emp,@SUM_Salary,@AVE_Salary,@New_SUM_Sala
ry,@New_AVE_Salary)
FETCH NEXT FROM SalaryDept INTO @Dept_No, @Dept_Name, @COUNT_Emp, @SUM_Salary, @AVE_Salary
END
END GO
Screenshots:
Output: