こんにちは、ねこです。

自称プログラマのおばちゃんのブログです。いろいろあるよねぇ~。

Microsoft MCSA SQL Server 2016 (70-761) むぼーな挑戦 7テーブル当てテスト

2019-11-03 16:03:01 | プログラム 勉強

A. Stored Procedure

B. View

C. Inline Table Valued Function (ITVF)-UDF-Table Defined Function

D. Multi-statement Table Valued Function (MSTVF)-UDF-Table Defined Function

E. Scalar Function

F. Common Table Expression(CTE)

G. Derived Tables

H. Indexed View (Clustered Index)

I. Indexed View (Non-clustered Index)


1.

create procedure dbo.usp_GetClients (
@clientName nvarchar(max) = null
)
as
begin;
select *
from dbo.Clients as a
where ((a.ClientName = @clientName) or a.ClientName is null)
end;

EXEC dbo.usp_GetClients('beerneko')


2.

CREATE VIEW hiredate_view
AS
SELECT p.FirstName, p.LastName, e.BusinessEntityID, e.HireDate
FROM HumanResources.Employee e
JOIN Person.Person AS p ON e.BusinessEntityID = p.BusinessEntityID;

SELECT * FROM hiredate_view


3.

CREATE VIEW product_master
WITH SCHEMABINDING
AS
SELECT
product_id,
product_name,
model_year,
list_price,
brand_name,
category_name
FROM
production.products p
INNER JOIN production.brands b
ON b.brand_id = p.brand_id
INNER JOIN production.categories c
ON c.category_id = p.category_id;

SELECT * FROM product_master


4.

CREATE FUNCTION Sales.ufn_SalesByStore (@storeid int)
RETURNS TABLE
AS
RETURN
(
SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS 'Total'
FROM Production.Product AS P
JOIN Sales.SalesOrderDetail AS SD ON SD.ProductID = P.ProductID
JOIN Sales.SalesOrderHeader AS SH ON SH.SalesOrderID = SD.SalesOrderID
JOIN Sales.Customer AS C ON SH.CustomerID = C.CustomerID
WHERE C.StoreID = @storeid
GROUP BY P.ProductID, P.Name
);
GO

SELECT * FROM Sales.ufn_SalesByStore (602);


5.

CREATE FUNCTION dbo.fn_getsubtree(@empid AS INT)
RETURNS @TREE TABLE
(
empid INT NOT NULL
,empname VARCHAR(25) NOT NULL
,mgrid INT NULL
,lvl INT NOT NULL
)
AS
BEGIN
WITH Employees_Subtree(empid, empname, mgrid, lvl)
AS
(
-- Anchor Member (AM)
SELECT empid, empname, mgrid, 0
FROM Employees
WHERE empid = @empid

UNION all

-- Recursive Member (RM)
SELECT e.empid, e.empname, e.mgrid, es.lvl+1
FROM Employees AS e
JOIN Employees_Subtree AS es
ON e.mgrid = es.empid
)
INSERT INTO @TREE
SELECT * FROM Employees_Subtree;

RETURN
END
GO


SELECT D.deptid,
D.deptname,
D.deptmgrid,
ST.empid,
ST.empname,
ST.mgrid
FROM Departments AS D
CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST;


6.

CREATE VIEW product_master
WITH SCHEMABINDING
AS
SELECT
product_id,
product_name,
model_year,
list_price,
brand_name,
category_name
FROM
production.products p
INNER JOIN production.brands b
ON b.brand_id = p.brand_id
INNER JOIN production.categories c
ON c.category_id = p.category_id;

SELECT * FROM product_master


7.

CREATE FUNCTION GetDiseasedPatientsNumber (@DiseaseCode INT)
RETURNS INT
AS
BEGIN
DECLARE @Number_of_Patients INT

SELECT @Number_of_Patients = COUNT(PatientID)
FROM [dbo].[Patients]
WHERE DiseaseCode = @DiseaseCode

RETURN @Number_of_Patients
END
GO

SELECT ProviderID
,[Provider Name]
,[Clinic Code]
,[dbo].[GetDiseasedPatientsNumber](DCode) AS 'Diabetes Patients Count'
FROM [dbo].[Provider]

 


8.

WITH cte_sales_amounts (staff, sales, year)

AS (
SELECT
first_name + ' ' + last_name,
SUM(quantity * list_price * (1 - discount)),
YEAR(order_date)
FROM
sales.orders o
INNER JOIN sales.order_items i ON i.order_id = o.order_id
INNER JOIN sales.staffs s ON s.staff_id = o.staff_id
GROUP BY
first_name + ' ' + last_name,
year(order_date)
)

SELECT
staff,
sales
FROM
cte_sales_amounts
WHERE
year = 2018;


9.

SELECT enter_month
FROM (
SELECT MONTH(enter_date) as enter_month
FROM wroks_on
) as m
GROUP BY enter_month


10.

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW dbo.product_master
WITH SCHEMABINDING
AS
SELECT COL001
,COL002
,COL003
,COL004
FROM dbo.TABLE_A

CREATE UNIQUE CLUSTERED INDEX PK_idxProduct_master
ON dbo.product_master ( COL001,COL002 )


11.

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW dbo.product_master
WITH SCHEMABINDING
AS
SELECT COL001
,COL002
,COL003
,COL004
FROM dbo.TABLE_A

CREATE NONCLUSTERED INDEX IDX_idxProduct_master
ON dbo.dbo.product_master ( COL003,COL004 )

 


12.

CREATE FUNCTION GetDiseasedPatientsNumber (@DiseaseCode INT)
RETURNS INT
AS
BEGIN
DECLARE @Number_of_Patients INT

SELECT @Number_of_Patients = COUNT(PatientID)
FROM [dbo].[Patients]
WHERE DiseaseCode = @DiseaseCode

RETURN @Number_of_Patients
END
GO

SELECT ProviderID
,[Provider Name]
,[Clinic Code]
FROM [dbo].[Provider]
WHERE [dbo].[GetDiseasedPatientsNumber](DiseaseCode) >= 150


Microsoft MCSA SQL Server 2016 (70-761) むぼーな挑戦 6(Stored ProcedureとTable Valued Function)

2019-11-03 13:21:19 | プログラム 勉強

はい、それではいろいろあるsqlステートメントの特色を見ていきます。これだけで結構、択一問題解けるようになりました。ふふふ。やっぱ、見て何の形なのかわからないとね。


 

【ストアードプロシージャとテーブル値関数】

https://stackoverflow.com/questions/40535519/when-would-you-use-a-table-valued-function

Inline Table-valued Function:

create function dbo.GetClients (
@clientName nvarchar(max) = null
)
returns table
return (
select *
from dbo.Clients as a
where ((a.ClientName = @clientName) or a.ClientName is null)
);

*リターンで返す値を整えていることに注目!『return (select *・・・』

Stored Procedure:

create procedure dbo.usp_GetClients (
@clientName nvarchar(max) = null
)
as
begin;
select *
from dbo.Clients as a
where ((a.ClientName = @clientName) or a.ClientName is null)
end;

*『beginとend』で返す値をを整えてたり、トランザクションなどの諸々のストアードプロシージャの表記がされていることに注目! 

Stored POrocedure アウトプット有:

CREATE PROCEDURE uspFindProductByModel (
@model_year SMALLINT,
@product_count INT OUTPUT
) AS
BEGIN
SELECT
product_name,
list_price
FROM
production.products
WHERE
model_year = @model_year;

SELECT @product_count = @@ROWCOUNT;
END;

*このSELECT文を二回使って変数を整えているところと、その方法『SELECT @product_count = @@ROWCOUNT;』に注目!

 

呼び出し方

テーブル値関数

select *

from dbo.GetClients(N'ACME') as a
join testTable as b
on a.ClientId = b.ClientId

ストアードプロシージャ

exec  dbo.usp_GetClients ()

ストアードプロシージャアウトプット有

DECLARE @count INT;
EXEC uspFindProductByModel
@model_year = 2018,
@product_count = @count OUTPUT;
SELECT @count AS 'Number of products found';

 


 【ややこしいネーミングの違い】

Programmable Data Objects

Stored Procedure

View

User Definded Funtion

|- Scalar Function

|- Table Valued Function

|- Inline Table Valued Function (ITVF)

|- Multi-statement Table Valued Function (MSTVF)

 

Table Expressions

Common Table Expression(CTE)

Inline Table Valued Function (ITVF)

Derived Tables

Views

 

これめちゃ悩みました...ObjectとExpresstionsの違いをしりませんでした。ほんとむぼーですよねぇ。。。どうやらProgrammable Data ObjectsはUDFを含めてユーザーが自分でプログラムして使いまわしができるようにするというものなのだそうです。そしてこのObjectとは、全く関係ないのがExpressionで、これはプログラムするどうのこうのではなく、データとして保有しないよ、あくまでもバーチャルだからね、というものだそうです。なるほど。だからViewはその場限りだから保有しない、そして自分でプログラムして使いまわしがきくという点で、Programmable Data Objectsなんですね。


【Programmable Data Objects】

Stored Procedure
  • 一つのファンクションのようにして呼びだし実行できる
  • DML(Insert,Update,Delete,etc)/DDL(Create,Drop,Alter,Trancate,etc)に使用できる
  • 使いまわしができる
  • パラメータIN・OUT、オッケー
  • Execで実行する
  • そのものを保存可能

View

  • インデックス付きにすることができる
  • バーチャルで実行する(データを変更できない、DML・DDLに使用できない)
  • パフォーマンスはあまりよくない
  • 一つ以上のViewをあたかもテーブルのように使うことができる
  • パラメータつかえません
  • そのものを保存可能
*Viewsはパラメータつかえませんが、User-Defined Functionsは使えます。
*Viewsはアウトプットを直接SELECT分でつかえませんが、User-Defined Functionsは使えます。
『*Views and User-Defined Functions almost serve the same purpose. But the major difference is that User-Defined Function can accept parameters, where as Views cannot. And also the output of the User Defined Function can be directly used in the SELECT clause, whereas you cannot do it with a View.』

User Definded Funtion

  • インプットパラメータ使えるけど、必ずリターン・バリューが必要
  • データを変更できない、DML・DDLに使用できない
  • そのものを保存可能
  • Scalar, ITVF(インライン値関数)、MSTVF(マルチステートメントテーブル)で、ITVFだけ『BEGIN・END』がつかえません。(と思います。。。)

 

|- Scalar Function

スカラーは一つしか値を返せません。SELECT文やWHERE, GROUP BY, HAVINGで使います。『RETURNS INT』と、データタイプをリターンで宣言してやらなければなりません。

『Scalar functions returns only scalar/single value. We can use Scalar function in SELECT statement, WHERE, GROUP BY, HAVING clause. We have to mention data type of that single data value in RETURNS clause of the function definition.』

CREATE FUNCTION GetDiseasedPatientsNumber(@DiseaseCode INT)
RETURNS INT
AS
BEGIN
DECLARE @Number_of_Patients INT

SELECT @Number_of_Patients= COUNT(PatientID)
FROM [dbo].[Patients]
WHERE DiseaseCode=@DiseaseCode

RETURN @Number_of_Patients
END
GO


<呼び出し方>

-- Use in Select statement

SELECT ProviderID
,[Provider Name]
,[Clinic Code]
,[dbo].[GetDiseasedPatientsNumber](DCode) AS 'Diabetes Patients Count'
FROM [dbo].[Provider]

-- Use in Where clause

SELECT ProviderID
,[Provider Name]
,[Clinic Code]
FROM [dbo].[Provider]
WHERE [dbo].[GetDiseasedPatientsNumber](DiseaseCode) >= 150

 

|- Table Valued Function

テーブル値関数ではスカラー値のように一つの値しか返すものではなく、横列のデータセットを返します(横行)。FROMやJOIN、SELECT文で使います。データの変更を行わずに保有するデータもなく、暫定的に値を返す点ではViewとほぼ同じ働きをしますが、Viewの代わりに使う理由として、Viewでは使うことのできないパラメータ値を設定することができます。時として「パラメータ化されたView」と呼ばれることもあります。

『A table valued user defined function returns a result set/row set instead of a single/scalar value. It can be invoked in FROM or JOIN clause of a SELECT query. Table valued function can be good alternative to a VIEW as VIEW does not allow parameters whereas table valued functions allow parameters. Sometimes they are called as ‘Parameterized Views’』

|- Inline Table Valued Function (ITVF)インライン値関数

インライン値関数はテーブル自体の変更をせずにそのまま返すだけに限ります。なのでスカラー値やMSTVF(マルチステートメントテーブル)とは違って、『RETURNS TABLE』のみです。

An inline table valued function definition specifies only RETURNS TABLE and not the table definition. The entire query batch or code or select query inside the function is a single RETURN statement.

CREATE FUNCTION CustomerProductDetails (@CustomerID NCHAR(5))
RETURNS TABLE
AS
RETURN (
SELECT C.CustomerID
,C.CompanyName
,C.City
,O.OrderID
,O.OrderDate
,P.ProductName
,OD.UnitPrice
,OD.Quantity
,OD.Discount
FROM [Products] P
INNER JOIN [Order Details] OD ON P.ProductID = OD.ProductID
INNER JOIN Orders O ON O.OrderID = OD.OrderID
INNER JOIN Customers C ON C.CustomerID = O.CustomerID
WHERE C.CustomerID = @CustomerID
)
GO

<呼び出し方>

-- Simple Select statement
SELECT *
FROM dbo.CustomerProductDetails('VINET')

-- JOIN with Employee TABLE
SELECT E.EmployeeID
,E.LastName
,E.FirstName
,E.Title
,CP.CustomerID
,CP.CompanyName
,CP.City
,CP.OrderID
,CP.OrderDate
,CP.EmployeeID
,CP.ProductName
,CP.UnitPrice
,CP.Quantity
,CP.Discount
FROM [Employees] E
JOIN dbo.CustomerProductDetails('VINET') CP ON CP.EmployeeID = E.EmployeeID

 

|- Multi-statement Table Valued Function (MSTVF)マルチステートメントテーブル

(MSTVF)マルチステートメントテーブルはプログラムされているものを実行でき、そして実行結果を『INSERT』使って一つのテーブルのなかに当てはめ、返す値とすることができる。でもね、これは実体のあるテーブルじゃないんだよ。バーチャルなんだよ。ってしつこいか。。。だって忘れちゃうんだもの。

A multi-statement TVF consist of code which is executed, where you do INSERT into the table variable, which is then returned from the function.

CREATE FUNCTION CustomerOrderDetails (@CustomerID NCHAR(5))
RETURNS @CustomerOrders TABLE (
CustomerID NCHAR(5)
,CompanyName NVARCHAR(40)
,OrderID INT
,OrderDate DATETIME
)
AS
BEGIN
INSERT INTO @CustomerOrders
SELECT C.CustomerID
,C.CompanyName
,O.OrderID
,O.OrderDate
FROM Customers C
INNER JOIN Orders O ON C.CustomerID = C.CustomerID
WHERE C.CustomerID = @CustomerID

IF @@ROWCOUNT = 0
BEGIN
INSERT INTO @CustomerOrders
VALUES (
''
,'No Orders Found'
,0
,GETDATE()
)
END

RETURN
END
GO 

*『@@ROWCOUNT 』で実行結果の行数をとれることに注目!


 
 
【4種類のTable Expression(テーブル値関数)
 
「*Objectとは、全く関係ないのがExpressionで、これはプログラムするどうのこうのではなく、データとしていちいち実体をもって保有しないよ、あくまでもバーチャルだからね」

先のほど上のほうでそう書きましたね。テンポラリーにつくられるデータセットで、ストアードプロシージャと違ってステートメント内で使えるけど、データそのものは変更できないのでしたね。(バーチャルで実行するのでデータを変更できない、DML・DDLに使用できない)

 

Common Table Expression(CTE)

UDFのTable-Valued Function (Inline Table Valued Function (ITVF)とMulti-statement Table Valued Function (MSTVF))

Derived Tables

Views

 

【Common Table Expression(CTE)】

  • WITHで始まり、返す値を設定してやる
  • 自分自身を呼び出せる
  • 一つ以上かきたせる

【UDFのTable-Valued Function (Inline Table Valued Function (ITVF)とMulti-statement Table Valued Function (MSTVF))】

  • Viewと似てるけど、パラメータを送れる点ですぐれている

テーブル値関数には二種類あります(忘れちゃったら上の「Table Valued Function」をもう一度みよう!)

【inline table valued function (ITVFインライン値関数) とmulti-statement table valued function (MSTVFマルチステートメントテーブル】

ITVF

CREATE FUNCTION Util.MyITVFunction (@Parameters INT)
RETURNS TABLE
AS
RETURN
SELECT TOP (@Parameters) N
FROM Util.Tally
ORDER BY N;
GO

MSTVF 

CREATE FUNCTION Util.MyMTVFunction (@Parameters INT)
RETURNS @FunctionResultTableVariable TABLE (N INT)
AS
BEGIN
INSERT INTO @FunctionResultTableVariable (N)
SELECT TOP (@Parameters) N
FROM Util.Tally
ORDER BY N;
RETURN;
END
GO

 

 

【Derived Tables】

  •  CTEとよく似てる
  • 自分自身を呼び出せない(CTEはできる)
  • 1つ以上書き足せない(CTEはできる)

【View】

*上にもう書いたのでそちらを見てね。

さて、次回はコードでどのコードがどのテーブルなのかテストを作ってみようと思います。

本当に、わかってんのかいな。。。ねこよ。。。