【1】什么是過程?過程與函數的區別?什么是存儲過程???
函數是帶返回值的過程
過程是沒有返回值的函數
存儲過程:存儲在數據庫中的封裝了若干條SQL語句的過程(MySql不支持不存儲的匿名過程)
【2】存儲過程的創建語法
MySQL:
create procedure procedureName()
begin
-- 存儲過程的編程
-- SQL statements
end;
SQLServer:
create procedure procedurename
@參數1名 類型 ,
@參數2 類型
as
begin
-- 存儲過程的編程
-- SQL statements
end
查看所有的procedure : show procedure status;
可給存儲過程傳遞參數
MySQL:
create procedure procedureName([in/out/inout] 參數名 參數類型.....)
其中的in/out/inout 是可選的,也就是說可有可無
in 默認缺省是in類型,為了函數內部使用的,調用時傳值 call proName(參數值)
out 外輸出參數,函數處理后,外部可調用(select @參數名)調用:call proName(@參數名)
SQLServer 無括號
inout 兼顧二者的特點
注意
:函數調用時,
in類型給傳值,call proName(參數值)
out類型給傳變量名(函數內部手動初始化)call proName(@參數名)
inout類型 需要傳一個已經定義了的變量
set @變量名:=變量初始值;
call proName(@變量名)
如:
MySQL:
create procedure p1(width int,height int)
begin
select concat('area is',width*height ) as area;
if width>height then
select 'you fat';
elseif width<height then
select 'you small';
else
select 'you ===';
end if;
end;
【3】存儲過程調用(MySQL) call procedureName()
【4】存儲過程的編程(MySQL)
- 存儲過程是可以編程的( 在begin 和 end 之間 ),可以有 變量,表達式,控制結構
(1)變量:
定義:用declare來聲明變量
格式:
declare 變量名 變量類型 default 默認初始值;
也可以給變量賦默認值 如 declare gnum int;賦值:set 變量名=值(或表達式); 如set gnum=gnum+old.much;
或者 set 變量名:=值,如 set gnum:=gunm+old.num;使用:直接使用
(2)表達式: +-*/%都可以正常的使用
(3)控制結構:
-
1)分支機構
①if雙分支
if search_condition then statement_list
[elseif search_condition then statement_list] ...
[else statement_list]
end if;
②case多分支
case 變量
when 常量 then 表達式;
when 常量 then 表達式;
when 常量 then 表達式;
else 表達式(都未中 相當于default);
end case;
- 2)循環結構
①while循環
while search_condition DO
...
statement_list
end while;
②repeat循環(相當于 do while)
repeat statement_list
until search_condition
end repeat;
【5】實例( C#調用SQL Server2008存儲過程,并封裝結果 )
需求
1.查詢全部的學生信息
2.插入一條學生的信息
1.創建學生表
為了方便演示,假設學生只有三個屬性 :學號,姓名,專業
/*
*@function:學生表
*@author:Stone6762
*/
create table student
(
id char(9) unique,
name char(50),
major char(64),
primary key (id),
);
2.創建存儲過程
-- =============================================
-- Author: Stone6762
-- Create date: 2016-10-1 08:12:05
-- Description: 獲取全部的學生信息
-- 無參的存儲過程的創建
-- =============================================
CREATE PROCEDURE Stu_GetAll
AS
BEGIN
SELECT id,name,major FROM student ORDER BY id;
END
-- =============================================
-- Author: Stone6762
-- Create date: 2016-10-1 09:31:08
-- Description: 學生表的插入
-- 有參的存儲過程的創建
-- =============================================
CREATE PROCEDURE Stu_Insert
@Nid varchar(9) ,
@Nname varchar(50),
@Nmajor varchar(7)
AS
BEGIN
insert into student(id,name,major)values(@Nid,@Nname,@Nmajor);
END
3. C# 鏈接數據庫,調用存儲過程,并將數據封裝
public class MySSDBSP
{
struct Student
{
public string id;
public string name;
public string major;
}
//因為會多次調用SqlConnection,故此將其寫入構造函數里
private SqlConnection myConnection = null;
public OFWZ3()
{
//讀取配置文件里的數據庫連接信息
//server=服務器名;uid=賬號;pwd=密碼;database=要連接的數據庫;Trusted_Connection=no
StreamReader sr = new StreamReader("文件名路徑\\Config.txt", Encoding.UTF8);
string connInfor = sr.ReadLine().Trim();
sr.Close();
myConnection = new SqlConnection(connInfor);
}
#region 操作學生表
/// 將學生的信息存儲到數據庫中
protected bool MyStuSave2DB(Student s)
{
//1.獲取鏈接-->構造函數已經做了
//2.建立可以執行SQL語句的SqlCommand
SqlCommand MyCommand = new SqlCommand("Stu_Insert", myConnection); //定義一個數據庫操作指令
//3.指明調用的是存儲過程
MyCommand.CommandType = CommandType.StoredProcedure;//設置該語句是讀取存儲過程的
//4.給存儲過程傳遞參數
SqlParameter id = new SqlParameter("@Nid", s.id);
SqlParameter name = new SqlParameter("@Nname", s.name);
SqlParameter major = new SqlParameter("@Nmajor", s.major);
MyCommand.Parameters.Add(id);
MyCommand.Parameters.Add(name);
MyCommand.Parameters.Add(major);
//5.執行存儲過程
try//異常處理
{
myConnection.Open();
MyCommand.ExecuteNonQuery();
myConnection.Close();
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
return true;
}
/// 讀取學生表中所有的數據
protected Student[] getAllStuFromDB()
{
//1.獲取鏈接--->構造函數已經做了
//2..建立可以執行SQL語句的SqlCommand
SqlCommand MyCommand = new SqlCommand("Stu_GetAll", myConnection); //定義一個數據庫操作指令
//3.指明調用的是存儲過程
MyCommand.CommandType = CommandType.StoredProcedure;//設置該語句是讀取存儲過程的
//4.設置數據適配器
SqlDataAdapter SelectAdapter = new SqlDataAdapter();//定義一個數據適配器
SelectAdapter.SelectCommand = MyCommand;//定義數據適配器的操作指令
//5.執行存儲過程
try
{
myConnection.Open();//打開數據庫連接
SelectAdapter.SelectCommand.ExecuteNonQuery();//執行數據庫查詢指令
myConnection.Close();//關閉數據庫
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
//6.將結果存儲到DataSet里
DataSet MyDataSet = new DataSet();//定義一個數據集
SelectAdapter.Fill(MyDataSet);//填充數據集
//7.解析DataSet中的數據,并將其封裝到Student數組里
DataTable dt = MyDataSet.Tables[0];//獲取查詢的結果表(因為只有一個)
return getStuFroTable(dt);//將DataTable里存儲的學生信息封裝到結構體數組里
}
/// 將DataTable里存儲的學生信息封裝到結構體數組里
private Student[] getStuFroTable(DataTable dt)
{
Student[] students = new Student[dt.Rows.Count];
for (int i = 0; i < dt.Rows.Count; i++)//遍歷行
{
students[i].id = dt.Rows[i]["id"].Trim();
students[i].name = ((string)dt.Rows[i]["name"]).Trim();
students[i].major = ((string)dt.Rows[i]["major"]).Trim();
}
return students;
}
#endregion
}