1,当Result Set是single row时,需要定义三个变量来接收数据,变量的DataType要和Column的DataType保持一致,并且在Result Set中指定返回的Column和接收的Variable之间的Mapping。在下游组件中,通过变量来引用Execute Sql Task的返回值。
2,当Result Set是Full Result Set时,返回的结果集使用0来代替其名称,返回的结果集存储在一个 Object类型的变量中,这个 OBJECT 类型在内部以集合的形式存在并保存整个查询结果集。
Result Name是0,将结果集存储在Object的SSIS Variable中。
3,如何使用Object类型的变量,object类型的变量实际上是一个Dataset,每一行数据都要被提取出来,存放到变量中,才能被其他组件使用,所以必须定义SSIS Variable 来保存数据。
在Foreach Loop 组件中,Enumerator选择Foreach ado enumator,在Ado Object Source Variable列表中选择User::VarObj。
创建三个变量来存放数据,变量的数据类型要和object中的column的数据类型保持一致,否则ssis 会报错。
在Variable Mappings中设置Ojbect的Column和变量的Mapping,index=0,表示的是object的第一个column,使用User::VarCode来存放第一个column的数据,依次类推。
Execute Sql Task 的Result DataSet如何返回
标签:
小编还为您整理了以下内容,可能对您也有帮助:
execute函数的用法
tempcon是个ADO用来连接数据库的智能指针,Execute方法用来执行sql语句。如果这条语句有数据返回,比如select。那么返回结果就给了temprecord。
输入值的集合X被称为f的定义域;可能的输出值的集合Y被称为f的值域。函数的值域是指定义域中全部元素通过映射f得到的实际输出值的集合。注意,把对应域称作值域是不正确的,函数的值域是函数的对应域的子集。
计算机科学中,参数和返回值的数据类型分别确定了子程序的定义域和对应域。因此定义域和对应域是函数一开始就确定的强制进行约束。另一方面,值域是和实际的实现有关。
函数与不等式和方程存在联系(初等函数)。令函数值等于零,从几何角度看,对应的自变量的值就是图像与X轴的交点的横坐标。
从代数角度看,对应的自变量是方程的解。另外,把函数的表达式(无表达式的函数除外)中的“=”换成“<”或“>”,再把“Y”换成其它代数式,函数就变成了不等式,可以求自变量的范围。
如何接收sql语句执行.的返回值
获取存储过程返回值及代码中获取返回值
1.OUPUT参数返回值
例: 向Order表插入一条记录,返回其标识
CREATE PROCEDURE [dbo].[nb_order_insert](
@o_buyerid int ,
@o_id bigint OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
BEGIN
INSERT INTO [Order](o_buyerid )
VALUES (@o_buyerid )
SET @o_id = @@IDENTITY
END
END
存储过程中获得方法:
DECLARE @o_buyerid int
DECLARE @o_id bigint
EXEC [nb_order_insert] @o_buyerid ,o_id bigint
2.RETURN过程返回值
CREATE PROCEDURE [dbo].[nb_order_insert](
@o_buyerid int ,
@o_id bigint OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
IF(EXISTS(SELECT * FROM [Shop] WHERE [s_id] = @o_shopid))
BEGIN
INSERT INTO [Order](o_buyerid )
VALUES (@o_buyerid )
SET @o_id = @@IDENTITY
RETURN 1 — 插入成功返回1
END
ELSE
RETURN 0 — 插入失败返回0
END
存储过程中的获取方法
DECLARE @o_buyerid int
DECLARE @o_id bigint
DECLARE @result bit
EXEC @result = [nb_order_insert] @o_buyerid ,o_id bigint
3.SELECT 数据集返回值
CREATE PROCEDURE [dbo].[nb_order_select](
@o_id int
)
AS
BEGIN
SET NOCOUNT ON;
SELECT o_id,o_buyerid FROM [Order]
WHERE o_id = @o_id
GO
存储过程中的获取方法
(1)、使用临时表的方法
CREATE TABLE [dbo].[Temp](
[o_id] [bigint] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[o_buyerid] [int] NOT NULL
)
INSERT [Temp] EXEC [nb_order_select] @o_id
– 这时 Temp 就是EXEC执行SELECT 后的结果集
SELECT * FROM [Temp]
DROP [Temp] — 删除临时表
(2)、速度不怎么样.(不推荐)
SELECT * from openrowset(’provider_name','Trusted_Connection=yes’,'exec nb_order_select’)
1.获取Return返回值
程序代码
//存储过程
//Create PROCEDURE MYSQL
// @a int,
// @b int
//AS
// return @a + @b
//GO
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
conn.Open();
SqlCommand MyCommand = new SqlCommand("MYSQL", conn);
MyCommand.CommandType = CommandType.StoredProcere;
MyCommand.Parameters.Add(new SqlParameter("@a", SqlDbType.Int));
MyCommand.Parameters["@a"].Value = 10;
MyCommand.Parameters.Add(new SqlParameter("@b", SqlDbType.Int));
MyCommand.Parameters["@b"].Value = 20;
MyCommand.Parameters.Add(new SqlParameter("@return", SqlDbType.Int));
MyCommand.Parameters["@return"].Direction = ParameterDirection.ReturnValue;
MyCommand.ExecuteNonQuery();
Response.Write(MyCommand.Parameters["@return"].Value.ToString());
2.获取Output输出参数值
程序代码
//存储过程
//Create PROCEDURE MYSQL
// @a int,
// @b int,
// @c int output
//AS
// Set @c = @a + @b
//GO
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
conn.Open();
SqlCommand MyCommand = new SqlCommand("MYSQL", conn);
MyCommand.CommandType = CommandType.StoredProcere;
MyCommand.Parameters.Add(new SqlParameter("@a", SqlDbType.Int));
MyCommand.Parameters["@a"].Value = 20;
MyCommand.Parameters.Add(new SqlParameter("@b", SqlDbType.Int));
MyCommand.Parameters["@b"].Value = 20;
MyCommand.Parameters.Add(new SqlParameter("@c", SqlDbType.Int));
MyCommand.Parameters["@c"].Direction = ParameterDirection.Output;
MyCommand.ExecuteNonQuery();
Response.Write(MyCommand.Parameters["@c"].Value.ToString());
C#接收存储过程返回值:
public static int User_Add(User us)
{
int iRet;
SqlConnection conn = new SqlConnection(Conn_Str);
SqlCommand cmd = new SqlCommand("User_Add", conn);
cmd.CommandType = CommandType.StoredProcere;
cmd.Parameters.AddWithValue("@UName", us.UName);
cmd.Parameters.AddWithValue("@UPass", us.UPass);
cmd.Parameters.AddWithValue("@PassQuestion", us.PassQuestion);
cmd.Parameters.AddWithValue("@PassKey", us.PassKey);
cmd.Parameters.AddWithValue("@Email", us.Email);
cmd.Parameters.AddWithValue("@RName", us.RName);
cmd.Parameters.AddWithValue("@Area", us.Area);
cmd.Parameters.AddWithValue("@Address", us.Address);
cmd.Parameters.AddWithValue("@ZipCodes", us.ZipCodes);
cmd.Parameters.AddWithValue("@Phone", us.Phone);
cmd.Parameters.AddWithValue("@QQ", us.QQ);
cmd.Parameters.Add("@RETURN_VALUE", "").Direction = ParameterDirection.ReturnValue;
try
{
conn.Open();
cmd.ExecuteNonQuery();
iRet = (int)cmd.Parameters["@RETURN_VALUE"].Value;
}
catch (SqlException ex)
{
throw ex;
}
finally
{
conn.Close();
}
return iRet;
}
C#接收存储过程输出参数:
public static decimal Cart_UserAmount(int UID)
{
decimal iRet;
SqlConnection conn = new SqlConnection(Conn_Str);
SqlCommand cmd = new SqlCommand("Cart_UserAmount", conn);
cmd.CommandType = CommandType.StoredProcere;
cmd.Parameters.AddWithValue("@UID", UID);
cmd.Parameters.Add("@Amount", SqlDbType.Decimal).Direction=ParameterDirection.Output;
try
{
conn.Open();
cmd.ExecuteNonQuery();
iRet = (decimal)cmd.Parameters["@Amount"].Value;
}
catch (SqlException ex)
{
throw ex;
}
finally
{
conn.Close();
}
return iRet;
}
//////////////////////////////////////////////////////////////
SQL 2000用户自定义函数 一。SQL Server 的三种自定义函数
“自定义函数”是我们平常的说法,而“用户定义的函数”是 SQL Server 中书面的说法。
SQL Server 2000 允许用户创建自定义函数,自定义函数可以有返回值。
自定义函数分为:标量值函数或表值函数
•如果 RETURNS 子句指定一种标量数据类型,则函数为标量值函数。可以使用多条 Transact-SQL 语句定义标量值函数。
•如果 RETURNS 子句指定 TABLE,则函数为表值函数。
表值函数又可分为:内嵌表值函数(行内函数)或多语句函数
•如果 RETURNS 子句指定的 TABLE 不附带列的列表,则该函数为内嵌表值函数。
•如果 RETURNS 子句指定的 TABLE 类型带有列及其数据类型,则该函数是多语句表值函数。
标量值函数示例
CREATE FUNCTION dbo.Foo()
RETURNS int
AS
BEGIN
declare @n int
select @n=3
return @n
END
create function GetSex(@sex int)
returns varchar(2)-- 用nvarchar(1)
as -- nvarchar:不管是一个字符还是一个汉字,都存为2个字节
begin -- varchar:汉字是2个字节,其他字符存为1个字节
declare @ssex varchar(2)-- 用nvarchar(1)
if(@sex=1)
set @ssex='男'
else
set @ssex='女'
return (@ssex)
end
调用:
select id,username,dbo.GetSex(Sex) as sex ,loginnum from t_user
内嵌表值函数示例
CREATE FUNCTION dbo.Foo()
RETURNS TABLE
AS
return select id, title from msgs
内嵌表值函数只有一个 select 语句。
多语句表值函数示例(部分)
CREATE FUNCTION FindUsers (@userid int )
RETURNS @FindUser TABLE (id int primary key, UserName varchar(30), RegDateTime DateTime,LoginNum int)
as
begin
insert into @FindUser Select ID, UserName,RegDateTime,LoginNum From T_User Where ID=@userid
return
end
调用:
SELECT * FROM FindUsers(6)
注意其 RETURNS 部分。
多语句函数的主体中允许使用以下语句。未在下面的列表中列出的语句不能用在函数主体中。
•赋值语句。
•控制流语句。
•DECLARE 语句,该语句定义函数局部的数据变量和游标。
•SELECT 语句,该语句包含带有表达式的选择列表,其中的表达式将值赋予函数的局部变量。
•游标操作,该操作引用在函数中声明、打开、关闭和释放的局部游标。只允许使用以 INTO 子句向局部变量赋值的 FETCH 语句;不允许使用将数据返回到客户端的 FETCH 语句。
•INSERT、UPDATE 和 DELETE 语句,这些语句修改函数的局部 table 变量。
•EXECUTE 语句调用扩展存储过程。
二.如何调用自定义函数
调用自定义函数(用户定义的函数)和调用内置函数方式基本相同,
•当调用标量值函数时,必须加上“所有者”,通常是 dbo(但不是绝对,可以在企业管理器中的“用户定义的函数”中查看所有者)。
•当调用表值函数时,可以只使用函数名称。
示例
SELECT *
select dbo.Sta(cnt) from tbl
示例
SELECT *
FROM fn_MyTableFunc( 123.09, N'O''Neill' )
三。存储过程和自定义函数的区别
存储过程(用户定义的存储过程)和自定义函数(用户定义的函数)的区别,在网上已经有讨论过,但有些显得过于零散,有些又篇幅过长不能保证每个人都细心阅读。这里作一个归纳,当然只是应用层面的,可能不全面。
•存储过程,功能强大,可以执行包括修改表等一系列数据库操作,也可以创建为 SQL Server 启动时自动运行的存储过程。
•自定义函数,用户定义函数不能用于执行一组修改全局数据库状态的操作。
•存储过程,可以使用非确定函数。
•自定义函数,不允许在用户定义函数主体中内置非确定函数。
•存储过程,可返回记录集。
•自定义函数,可以返回表变量。
•存储过程,其返回值不能被直接引用。
•自定义函数,其返回值可以被直接引用。
•存储过程,用 EXECUTE 语句执行。
•自定义函数,在查询语句中调用。
如何精确获取sql返回的dataset中对应的table
目前.NET的驱动无法在SQL返回到ADO.NET是自动设置TableName属性,
可以参考的简介实现:
SQL脚本 :select 'tbA','tbB','tbC'
select * from tbA
select * from tbB
select * from tbC
前端程序完成映射供其他模块以ds.Tables["A"]命名方式调用:
int i = 1;
foreach (string tablename in dsData.Tables[0].Rows[0][0].ToString().Split(','))
{
dsData.Tables[i++].TableName = tablename;
}
还有存储过程参数方式、但仍要前端进行一次映射:Create procere getQuery (@tb1 varchar(50) output,@tb2 varchar(50) output)
AS
set @tb1='tbA'
set @tb2 'tbB'
select * from tbA
select * from tbB
或者:
Create procere getQuery()
AS
select * from tbA
select * from tbB
return 'tbA,tbB'
在delphi中调用存储过程的时候,怎样返回记录集
【delphi+oracle报表解决方案(一)】delphi中调用oracle的存储过程(分带返回游标,不返回值两种)
关键字: delphi ,oracle存储过程,游标,返回数据集,报表
注:delphi 6+ oracle 8.1.6
一.创建包与包体
1.附:建表aaclass为下面作测试用
create table aaclass(CID VARCHAR2(50), CNAME VARCHAR2(50), pnumber NUMBER(10,0) );
INSERT INTO aaclass values('c1', 'cn1', 10 ) ;
INSERT INTO aaclass values('c2', 'cn2', 40 ) ;
INSERT INTO aaclass values('c1', 'cn3', 30 ) ;
commit;
2.建包:
CREATE OR REPLACE PACKAGE PKG_JCCTEST1
AS
type rc_class is ref cursor;
--求p1,p2的和与差,返回的多个值通过游标返回
procere GetSubAndSum2(p1 number,p2 number ,
ResultCursor out rc_class);
--查询满足条件的数据集,返回数据集通过游标返回
procere GetClass2(a in number,ResultCursor out rc_class ) ;
--往表中插一条记录,不返回结果集时,本人用AdoQuery调用(adodataset好象要求必须返回结果集)
procere InsertClass( p_cid varchar2 ,p_cname varchar2 ,
p_pnumber number) ;
end PKG_JCCTEST1;
3.建包体
CREATE OR REPLACE PACKAGE BODY PKG_JCCTEST1
AS
procere GetSubAndSum2(p1 number,p2 number ,
ResultCursor out rc_class)
IS
BEGIN
open ResultCursor for
select p1-p2 as "sum", p1+p2 as "sub" from al;
END ;
procere GetClass2(a in number,ResultCursor out rc_class )
is
begin
open ResultCursor for
select aaclass.* from aaclass where pnumber >a;
end ;
procere InsertClass( p_cid varchar2 ,p_cname varchar2 ,
p_pnumber number)
is
begin
insert into aaclass values(p_cid,p_cname,p_pnumber) ;
-- commit;
end ;
二.在delphi中利用AdoDataSet调用上述第一个存储过程
1.利用AdoConnection1连接数据库(驱动为 oracle Provider for OLE DB),
**并在连接字符串中加入这一节: PLSQLRSet=1; 如下所示:
Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=1
2.在窗体上加AdoDataSet1 指明连接为上述AdoConnection1,下面可以放一个按钮,单击按钮就能调用第一步中创建的包过程,并返回数据集。代码如下所示:
procere TForm1.Button1Click(Sender: TObject);
var
AResult , BResult : integer;
begin
ADODataSet1.Close ;
ADODataSet1.CommandType := cmdText ;
ADODataSet1.Parameters.Clear ;
//***利用call方法调用oracle过程时,参数必须由?来传, 即使你要传的参数为常理
//输出游标的参数不需要指定!!!!!!,本来此函数带三个参数,我们这里只需要传两个参数.
ADODataSet1.CommandText := '{call PKG_JCCTEST1.GetSubAndSum2(?,?)}' ;
//***C 顺序有关,createparam必须放在commandtext赋值语句之后.
// 创建第一个参数,对应call中的第一个?,ftinteger为类型,10为长度,45为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,45);
//创建第二个参数,根据createparameter的顺序 自动与call中的第二个参数对应
ADODataSet1.Parameters.CreateParameter('p2',ftinteger,pdinput,10,4);
//下面调用ADODataSet1 的open方法,返回数据集(对应包过程的游标)
ADODataSet1.Open ;
//根据存储过程,数据集只有一条记录,所以不需要用while do 来遍历数据集,直接取数据了
//此处的字段名根据包过程中的返回游标 对应的字段名来取
//定义的存储过程返回游标如: open ResultCursor for
// select p1-p2 as "sum", p1+p2 as "sub" from al;
//把对应的字段值取出来即可
AResult := ADODataSet1.Fields.FieldByName('sub').Value ;
BResult := ADODataSet1.Fields.FieldByName('sum').Value ;
//显示结果
showmessage(inttostr(AResult)) ;
showmessage(inttostr(BResult)) ;
end;
三.在delphi中利用AdoDataSet调用上述第二个存储过程
还是利用上述的AdoDataSet1来调用第二个存储过程,无需任何改动,加第二个按钮,单击时代码如下:
procere TForm1.Button2Click(Sender: TObject);
begin
ADODataSet1.Close ;
ADODataSet1.CommandType := cmdText ;
ADODataSet1.Parameters.Clear ;
//***利用call方法调用oracle过程时,参数必须由?来传, 即使你要传的参数为常理
//输出游标的参数不需要指定!!!!!!,本来此函数带两个参数,我们这里只需要传一个参数.
ADODataSet1.CommandText := '{call PKG_JCCTEST1.GetClass2(?)}' ;
//***C 顺序有关,createparam必须放在commandtext赋值语句之后.
// 创建第一个参数,对应call中的第一个?,ftinteger为类型,10为长度,20为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,20);
//下面调用ADODataSet1 的open方法,返回数据集(对应包过程的游标)
ADODataSet1.Open ;
while not ADODataSet1.Eof do
begin
showmessage('CID : '+string(ADODataSet1.FieldByName('CID').Value) +
'--CNAME :' + string(ADODataSet1.FieldByName('CNAME').Value) +
'--PNUMBER :' + string(ADODataSet1.FieldByName('PNUMBER').Value)
) ;
ADODataSet1.Next ;
end ;
end;
四 利用adoquery调用第三个过程,不返回数据集的
procere TForm1.Button3Click(Sender: TObject);
begin
AdoQuery1.Close ;
AdoQuery1.Parameters.Clear ;
AdoQuery1.SQL.Clear ;
AdoQuery1.SQL.Add('{call PKG_JCCTEST1.GetSubAndSum2(?,?)}') ;
AdoQuery1.Parameters.CreateParameter('P1',ftstring,pdinput, 50,'c11') ;
AdoQuery1.Parameters.CreateParameter('P2',ftstring,pdinput, 50,'cn11') ;
AdoQuery1.Parameters.CreateParameter('P3',ftinteger,pdinput, 50,25) ;
AdoQuery1.ExecSQL ;
end;
五 利用adoquery调用第一个过程,返回数据集的.
procere TForm1.Button4Click(Sender: TObject);
begin
AdoQuery1.Close ;
AdoQuery1.Parameters.Clear ;
AdoQuery1.SQL.Clear ;
AdoQuery1.SQL.Add('{call PKG_JCCTEST1.GetSubAndSum2(?,?)}') ;
AdoQuery1.Parameters.CreateParameter('P1',ftinteger,pdinput, 50,25) ;
AdoQuery1.Parameters.CreateParameter('P2',ftinteger,pdinput, 50,22) ;
AdoQuery1.Open ;
Showmessage(string( AdoQuery1.FieldByName('sub').Value)+'-'+
string( AdoQuery1.FieldByName('sum').Value));
end;
六.关于三层体系的此类问题
两层的解决了,三层类似.
中间层用tadodataset 或tadoquery (+tdatasetprovider),中间层的adoconnection的连接字符串加上plsqlRset=1;
客户端用clientdataset ,大同小异,举例如下:
begin
//调用相应的过程
ClientDataSet1.Close ;
ClientDataSet1.Params.Clear ;
ClientDataSet1.CommandText := '{call PackageName.ProcereName(?,?)}' ;
ClientDataSet1.Params.CreateParam(ftInteger , 'ParamName1', ptInput) ;
ClientDataSet1.Open ;
end ;
本人水平有限,如有不当与错误之处请指正!
--------------------------------------------------
问:你好:
看到你的关于DELPHI调用ORACLE存储过程返回结果集的文章,很受触发。
我已经实现了在DELPHI里调用ORACLE存储过程,通过一个游标参数,返回一个结果集的情况。现在有个问题:在存储过程里,可以实现多个弱游标参数输出多个结果集,但是,在DELPHI里,我不知道,怎么取得这第二个或其后的通过游标返回的结果集。通过ADO只能取得第一个结果集。
如果你知道解决方案,请EMAIL联系我。
不胜感激。
答:
用nextrecordset方法就可以了,代码如下:
var
vTemp1:integer;
begin
....
ADODataSet1.Open;
ADODataSet2.Recordset:=ADODataSet1.NextRecordset(vTemp1);
showmessage(ADODataSet2.FieldValues['CID']);
end;
问:怎么连接局域网内的oracle的数据呢?
连接字符串应该怎么写呢?
Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=1
我用的adoquery控件。
答:以下三个参数根据你的情况修改就可以了
Data Source=TNS名称
User ID=用户名
Password=密码
本文来自CSDN博客
在delphi中调用存储过程的时候,怎样返回记录集
【delphi+oracle报表解决方案(一)】delphi中调用oracle的存储过程(分带返回游标,不返回值两种)
关键字: delphi ,oracle存储过程,游标,返回数据集,报表
注:delphi 6+ oracle 8.1.6
一.创建包与包体
1.附:建表aaclass为下面作测试用
create table aaclass(CID VARCHAR2(50), CNAME VARCHAR2(50), pnumber NUMBER(10,0) );
INSERT INTO aaclass values('c1', 'cn1', 10 ) ;
INSERT INTO aaclass values('c2', 'cn2', 40 ) ;
INSERT INTO aaclass values('c1', 'cn3', 30 ) ;
commit;
2.建包:
CREATE OR REPLACE PACKAGE PKG_JCCTEST1
AS
type rc_class is ref cursor;
--求p1,p2的和与差,返回的多个值通过游标返回
procere GetSubAndSum2(p1 number,p2 number ,
ResultCursor out rc_class);
--查询满足条件的数据集,返回数据集通过游标返回
procere GetClass2(a in number,ResultCursor out rc_class ) ;
--往表中插一条记录,不返回结果集时,本人用AdoQuery调用(adodataset好象要求必须返回结果集)
procere InsertClass( p_cid varchar2 ,p_cname varchar2 ,
p_pnumber number) ;
end PKG_JCCTEST1;
3.建包体
CREATE OR REPLACE PACKAGE BODY PKG_JCCTEST1
AS
procere GetSubAndSum2(p1 number,p2 number ,
ResultCursor out rc_class)
IS
BEGIN
open ResultCursor for
select p1-p2 as "sum", p1+p2 as "sub" from al;
END ;
procere GetClass2(a in number,ResultCursor out rc_class )
is
begin
open ResultCursor for
select aaclass.* from aaclass where pnumber >a;
end ;
procere InsertClass( p_cid varchar2 ,p_cname varchar2 ,
p_pnumber number)
is
begin
insert into aaclass values(p_cid,p_cname,p_pnumber) ;
-- commit;
end ;
二.在delphi中利用AdoDataSet调用上述第一个存储过程
1.利用AdoConnection1连接数据库(驱动为 oracle Provider for OLE DB),
**并在连接字符串中加入这一节: PLSQLRSet=1; 如下所示:
Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=1
2.在窗体上加AdoDataSet1 指明连接为上述AdoConnection1,下面可以放一个按钮,单击按钮就能调用第一步中创建的包过程,并返回数据集。代码如下所示:
procere TForm1.Button1Click(Sender: TObject);
var
AResult , BResult : integer;
begin
ADODataSet1.Close ;
ADODataSet1.CommandType := cmdText ;
ADODataSet1.Parameters.Clear ;
//***利用call方法调用oracle过程时,参数必须由?来传, 即使你要传的参数为常理
//输出游标的参数不需要指定!!!!!!,本来此函数带三个参数,我们这里只需要传两个参数.
ADODataSet1.CommandText := '{call PKG_JCCTEST1.GetSubAndSum2(?,?)}' ;
//***C 顺序有关,createparam必须放在commandtext赋值语句之后.
// 创建第一个参数,对应call中的第一个?,ftinteger为类型,10为长度,45为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,45);
//创建第二个参数,根据createparameter的顺序 自动与call中的第二个参数对应
ADODataSet1.Parameters.CreateParameter('p2',ftinteger,pdinput,10,4);
//下面调用ADODataSet1 的open方法,返回数据集(对应包过程的游标)
ADODataSet1.Open ;
//根据存储过程,数据集只有一条记录,所以不需要用while do 来遍历数据集,直接取数据了
//此处的字段名根据包过程中的返回游标 对应的字段名来取
//定义的存储过程返回游标如: open ResultCursor for
// select p1-p2 as "sum", p1+p2 as "sub" from al;
//把对应的字段值取出来即可
AResult := ADODataSet1.Fields.FieldByName('sub').Value ;
BResult := ADODataSet1.Fields.FieldByName('sum').Value ;
//显示结果
showmessage(inttostr(AResult)) ;
showmessage(inttostr(BResult)) ;
end;
三.在delphi中利用AdoDataSet调用上述第二个存储过程
还是利用上述的AdoDataSet1来调用第二个存储过程,无需任何改动,加第二个按钮,单击时代码如下:
procere TForm1.Button2Click(Sender: TObject);
begin
ADODataSet1.Close ;
ADODataSet1.CommandType := cmdText ;
ADODataSet1.Parameters.Clear ;
//***利用call方法调用oracle过程时,参数必须由?来传, 即使你要传的参数为常理
//输出游标的参数不需要指定!!!!!!,本来此函数带两个参数,我们这里只需要传一个参数.
ADODataSet1.CommandText := '{call PKG_JCCTEST1.GetClass2(?)}' ;
//***C 顺序有关,createparam必须放在commandtext赋值语句之后.
// 创建第一个参数,对应call中的第一个?,ftinteger为类型,10为长度,20为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,20);
//下面调用ADODataSet1 的open方法,返回数据集(对应包过程的游标)
ADODataSet1.Open ;
while not ADODataSet1.Eof do
begin
showmessage('CID : '+string(ADODataSet1.FieldByName('CID').Value) +
'--CNAME :' + string(ADODataSet1.FieldByName('CNAME').Value) +
'--PNUMBER :' + string(ADODataSet1.FieldByName('PNUMBER').Value)
) ;
ADODataSet1.Next ;
end ;
end;
四 利用adoquery调用第三个过程,不返回数据集的
procere TForm1.Button3Click(Sender: TObject);
begin
AdoQuery1.Close ;
AdoQuery1.Parameters.Clear ;
AdoQuery1.SQL.Clear ;
AdoQuery1.SQL.Add('{call PKG_JCCTEST1.GetSubAndSum2(?,?)}') ;
AdoQuery1.Parameters.CreateParameter('P1',ftstring,pdinput, 50,'c11') ;
AdoQuery1.Parameters.CreateParameter('P2',ftstring,pdinput, 50,'cn11') ;
AdoQuery1.Parameters.CreateParameter('P3',ftinteger,pdinput, 50,25) ;
AdoQuery1.ExecSQL ;
end;
五 利用adoquery调用第一个过程,返回数据集的.
procere TForm1.Button4Click(Sender: TObject);
begin
AdoQuery1.Close ;
AdoQuery1.Parameters.Clear ;
AdoQuery1.SQL.Clear ;
AdoQuery1.SQL.Add('{call PKG_JCCTEST1.GetSubAndSum2(?,?)}') ;
AdoQuery1.Parameters.CreateParameter('P1',ftinteger,pdinput, 50,25) ;
AdoQuery1.Parameters.CreateParameter('P2',ftinteger,pdinput, 50,22) ;
AdoQuery1.Open ;
Showmessage(string( AdoQuery1.FieldByName('sub').Value)+'-'+
string( AdoQuery1.FieldByName('sum').Value));
end;
六.关于三层体系的此类问题
两层的解决了,三层类似.
中间层用tadodataset 或tadoquery (+tdatasetprovider),中间层的adoconnection的连接字符串加上plsqlRset=1;
客户端用clientdataset ,大同小异,举例如下:
begin
//调用相应的过程
ClientDataSet1.Close ;
ClientDataSet1.Params.Clear ;
ClientDataSet1.CommandText := '{call PackageName.ProcereName(?,?)}' ;
ClientDataSet1.Params.CreateParam(ftInteger , 'ParamName1', ptInput) ;
ClientDataSet1.Open ;
end ;
本人水平有限,如有不当与错误之处请指正!
--------------------------------------------------
问:你好:
看到你的关于DELPHI调用ORACLE存储过程返回结果集的文章,很受触发。
我已经实现了在DELPHI里调用ORACLE存储过程,通过一个游标参数,返回一个结果集的情况。现在有个问题:在存储过程里,可以实现多个弱游标参数输出多个结果集,但是,在DELPHI里,我不知道,怎么取得这第二个或其后的通过游标返回的结果集。通过ADO只能取得第一个结果集。
如果你知道解决方案,请EMAIL联系我。
不胜感激。
答:
用nextrecordset方法就可以了,代码如下:
var
vTemp1:integer;
begin
....
ADODataSet1.Open;
ADODataSet2.Recordset:=ADODataSet1.NextRecordset(vTemp1);
showmessage(ADODataSet2.FieldValues['CID']);
end;
问:怎么连接局域网内的oracle的数据呢?
连接字符串应该怎么写呢?
Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=1
我用的adoquery控件。
答:以下三个参数根据你的情况修改就可以了
Data Source=TNS名称
User ID=用户名
Password=密码
本文来自CSDN博客
sqlserver存储过程: Exec(@变量)在一个存储过程中调用如何有参数返回变量查询值
set nocount on
go
create proc proc_find_count
@column_name varchar(20),
@term varchar(20)
as
declare @sel varchar(500)
set @sel = 'select count(*) from proct where '+@column_name+' like ''%'+@term+'%'''
Exec(@sel)
go
declare @count varchar(20)
exec proc_find_count 'p_name','c'
你的@count没有任何作用,这样就可以足够了,你试下
delphi客户端调用存储过程返回参数,请问怎么解决1
开发环境:Delphi XE 10.1 Update 2
服务器:FDConnection1-->FDQuery1-->DataSetProvider1
客户端:SQLConnection1-->DSProviderConnection1-->ClientDataSet5
procere TFrame01_Frame.Button3Click(Sender: TObject);
begin
ClientDataSet5.Close;
// FormID、Opid是传入值,doccode是传出值 注意参数不能带@,传出值不要加output,传入、传出类型已在CreateParam时指定了
ClientDataSet5.CommandText := ' Execute _sysP_NewDocCode :FormID,:Opid,:doccode ';
ClientDataSet5.Params.Clear;
ClientDataSet5.Params.CreateParam(ftString,'FormID',ptInput);
ClientDataSet5.Params.CreateParam(ftString,'Opid',ptInput);
ClientDataSet5.Params.CreateParam(ftString,'doccode',ptOutput);
ClientDataSet5.Params.ParamByName('FormID').Size := 30;
ClientDataSet5.Params.ParamByName('FormID').Value :='Sale2002';
ClientDataSet5.Params.ParamByName('Opid').Size := 20;
ClientDataSet5.Params.ParamByName('Opid').Value :='191025';
ClientDataSet5.Params.ParamByName('doccode').Size := 20;
ClientDataSet5.Execute;//如果不返回结果集,执行此语句
//ClientDataSet5.Open;
Edit2.Text := ClientDataSet5.Params.ParamByName('doccode').Value;
end;
特别注意:参数不能带@,传出值不要加output,传入、传出类型已在CreateParam时指定了,这两坑有点深耗费多天时间查询资料以及摸索。
希望能够对大家有用,少走些弯路,同大家结菩提缘
delphi客户端调用存储过程返回参数,请问怎么解决1
开发环境:Delphi XE 10.1 Update 2
服务器:FDConnection1-->FDQuery1-->DataSetProvider1
客户端:SQLConnection1-->DSProviderConnection1-->ClientDataSet5
procere TFrame01_Frame.Button3Click(Sender: TObject);
begin
ClientDataSet5.Close;
// FormID、Opid是传入值,doccode是传出值 注意参数不能带@,传出值不要加output,传入、传出类型已在CreateParam时指定了
ClientDataSet5.CommandText := ' Execute _sysP_NewDocCode :FormID,:Opid,:doccode ';
ClientDataSet5.Params.Clear;
ClientDataSet5.Params.CreateParam(ftString,'FormID',ptInput);
ClientDataSet5.Params.CreateParam(ftString,'Opid',ptInput);
ClientDataSet5.Params.CreateParam(ftString,'doccode',ptOutput);
ClientDataSet5.Params.ParamByName('FormID').Size := 30;
ClientDataSet5.Params.ParamByName('FormID').Value :='Sale2002';
ClientDataSet5.Params.ParamByName('Opid').Size := 20;
ClientDataSet5.Params.ParamByName('Opid').Value :='191025';
ClientDataSet5.Params.ParamByName('doccode').Size := 20;
ClientDataSet5.Execute;//如果不返回结果集,执行此语句
//ClientDataSet5.Open;
Edit2.Text := ClientDataSet5.Params.ParamByName('doccode').Value;
end;
特别注意:参数不能带@,传出值不要加output,传入、传出类型已在CreateParam时指定了,这两坑有点深耗费多天时间查询资料以及摸索。
希望能够对大家有用,少走些弯路,同大家结菩提缘
PL/SQL里 execute immediate的用法 谁给解释下
execute 为SQL命令,意为执行存储过程,immediate 为执行的存储过程名称。
以下摘自MsSql帮助,别怪我复制哦,实在是帮助里描述的才最全面。
EXECUTE
执行标量值的用户定义函数、系统过程、用户定义存储过程或扩展存储过程。同时支持 Transact-SQL 批处理内的字符串的执行
若要唤醒调用函数,请使用 EXECUTE stored_procere 中描述的语法。
语法
执行存储过程:
[ [ EXEC [ UTE ] ]
{
[ @return_status = ]
{ procere_name [ ;number ] | @procere_name_var
}
[ [ @parameter = ] { value | @variable [ OUTPUT ] | [ DEFAULT ] ]
[ ,...n ]
[ WITH RECOMPILE ]
执行字符串:
EXEC [ UTE ] ( { @string_variable | [ N ] 'tsql_string' } [ + ...n ] )
参数
@return_status
是一个可选的整型变量,保存存储过程的返回状态。这个变量在用于 EXECUTE 语句前,必须在批处理、存储过程或函数中声明过。
在用于唤醒调用标量值用户定义函数时,@return_status 变量可以是任何标量数据类型。
procere_name
是拟调用的存储过程的完全合法或者不完全合法的名称。过程名称必须符合标识符规则。有关更多信息,请参见使用标识符。无论服务器的代码页或排序方式如何,扩展存储过程的名称总是区分大小写。
用户可以执行在另一数据库中创建的过程,只要该用户拥有此过程或有在该数据库中执行它的适当的权限。用户可以在另一台运行 Microsoft® SQL Server™ 的服务器上执行过程,只要该用户有适当的权限使用该服务器(远程访问),并能在数据库中执行该过程。如果指定了服务器名称但没有指定数据库名称,SQL Server 会在用户默认的数据库中寻找该过程。
;number
是可选的整数,用于将相同名称的过程进行组合,使得它们可以用一句 DROP PROCEDURE 语句除去。该参数不能用于扩展存储过程。
在同一应用程序中使用的过程一般都以该方式组合。例如,在订购应用程序中使用的过程可以 orderproc;1、orderproc;2 等来命名。DROP PROCEDURE orderproc 语句将除去整个组。在对过程分组后,不能除去组中的单个过程。例如,DROP PROCEDURE orderproc;2 是不允许的。有关过程组的更多信息,请参见 CREATE PROCEDURE。
@procere_name_var
是局部定义变量名,代表存储过程名称。
@parameter
是过程参数,在 CREATE PROCEDURE 语句中定义。参数名称前必须加上符号 (@)。在以 @parameter_name = value 格式使用时,参数名称和常量不一定按照 CREATE PROCEDURE 语句中定义的顺序出现。但是,如果有一个参数使用 @parameter_name = value 格式,则其它所有参数都必须使用这种格式。
默认情况下,参数可为空。如果传递 NULL 参数值,且该参数用于 CREATE 或 ALTER TABLE 语句中不允许为 NULL 的列(例如,插入至不允许为 NULL 的列),SQL Server 就会报错。为避免将 NULL 参数值传递给不允许为 NULL 的列,可以在过程中添加程序设计逻辑或采用默认值(使用 CREATE 或 ALTER TABLE 语句中的 DEFAULT 关键字)。
value
是过程中参数的值。如果参数名称没有指定,参数值必须以 CREATE PROCEDURE 语句中定义的顺序给出。
如果参数值是一个对象名称、字符串或通过数据库名称或所有者名称进行,则整个名称必须用单引号括起来。如果参数值是一个关键字,则该关键字必须用双引号括起来。
如果在 CREATE PROCEDURE 语句中定义了默认值,用户执行该过程时可以不必指定参数。如果该过程使用了带 LIKE 关键字的参数名称,则默认值必须是常量,并且可以包含 %、_、[ ] 及 [^] 通配符。
默认值也可以为 NULL。通常,过程定义会指定当参数值为 NULL 时应该执行的操作。
@variable
是用来保存参数或者返回参数的变量。
OUTPUT
指定存储过程必须返回一个参数。该存储过程的匹配参数也必须由关键字 OUTPUT 创建。使用游标变量作参数时使用该关键字。
如果使用 OUTPUT 参数,目的是在调用批处理或过程的其它语句中使用其返回值,则参数值必须作为变量传递(即 @parameter = @variable)。如果一个参数在 CREATE PROCEDURE 语句中不是定义为 OUTPUT 参数,则对该参数指定 OUTPUT 的过程不能执行。不能使用 OUTPUT 将常量传递给存储过程;返回参数需要变量名称。在执行过程之前,必须声明变量的数据类型并赋值。返回参数可以是 text 或 image 数据类型以外的任意数据类型。
DEFAULT
根据过程的定义,提供参数的默认值。当过程需要的参数值没有事先定义好的默认值,或缺少参数,或指定了 DEFAULT 关键字,就会出错。
n
是占位符,表示在它前面的项目可以多次重复执行。例如,EXECUTE 语句可以指定一个或者多个 @parameter、value 或 @variable。
WITH RECOMPILE
强制编译新的计划。如果所提供的参数为非典型参数或者数据有很大的改变,使用该选项。在以后的程序执行中使用更改过的计划。该选项不能用于扩展存储过程。建议尽量少使用该选项,因为它消耗较多系统资源。
@string_variable
是局部变量的名称。@string_variable 可以是 char、varchar、nchar 或 nvarchar 数据类型,最大值为服务器的可用内存。如果字符串长度超过 4,000 个字符,则把多个局部变量串联起来用于 EXECUTE 字符串。有关系统提供的 SQL Server 数据类型更多的信息,请参见数据类型。
[N]'tsql_string'
是一个常量,tsql_string 可以是 nvarchar 或 varchar 数据类型。如果包含 N,则该字符串将解释为 nvarchar 数据类型,最大值为服务器的可用内存。如果字符串长度超过 4,000 个字符,则把多个局部变量串联起来用于 EXECUTE 字符串。
注释
如果过程名称的前三个字符为 sp_,SQL Server 会在 Master 数据库中寻找该过程。如果没能找到合法的过程名称,SQL Server 会寻找所有者名称为 dbo 的过程。若要将存储过程名称解析为与系统存储过程同名的用户定义存储过程,请提供一个完全合法的过程名称。
参数可以通过利用 value 或 @parameter_name = value 来提供。参数不是事务的一个部分;因而如果事务中的参数值更改,且该事务在以后回滚,该参数值不会退回到以前的值。返回给调用方的值总是过程返回时的值。
当一个存储过程调用另一个存储过程时,会产生嵌套。当调用的过程开始执行时,嵌套级会增加,当调用过程执行结束时,嵌套级则会减少。嵌套级最高为32级,超过32级时,会导致整个调用过程链失败。当前的嵌套级存储在 @@NESTLEVEL 函数中。
SQL Server 目前使用返回值 0 到 -14 来表示存储过程的执行状态。值 –15 到 -99 留作后用。有关保留的返回状态值的列表的更多信息,请参见 RETURN。
因为远程存储过程和扩展存储过程不在事务的作用域中(除非在 BEGIN DISTRIBUTED TRANSACTION 语句中发出或者是和不同的配置选项一起使用),所以通过调用执行的命令不能回滚。有关更多信息,请参见系统存储过程和 BEGIN DISTRIBUTED TRANSACTION。
当使用游标变量时,如果执行的过程传递一个分配有游标的游标变量,就会出错。
在执行存储过程时,如果语句是批处理中的第一个语句,则不一定要指定 EXECUTE 关键字。
使用带字符串的 EXECUTE 命令
使用字符串串联运算符 (+) 为动态执行创建长字符串。每个字符串表达式可以是 Unicode 与 non-Unicode 数据类型的混合。
尽管每个 [N] 'tsql_string' 或 @string_variable 不得超过 8,000 个字节,SQL Server 语法分析器中对这种串联只进行逻辑处理而不占用物理内存。例如,该语句决不会生成长 16,000 个串联起来的字符串:
EXEC('name_of_8000_char_string' + 'another_name_of_8000_char_string')
在 EXECUTE 语句执行前,不会编译 EXECUTE 语句内的语句。
数据库环境的更改只在 EXECUTE 语句结束前有效。例如,在这个例子的 EXEC 后,数据库环境是 master:
USE master EXEC ("USE pubs") SELECT * FROM authors
权限
存储过程的 EXECUTE 权限默认给该存储过程的所有者,该所有者可以将此权限转让给其他用户。当遇到 EXECUTE 语句时,即使 EXECUTE 语句是在存储过程中,也会检查在 EXECUTE 字符串内使用该语句的权限。当运行一个执行字符串的存储过程时,系统会在执行该过程的用户环境中,而不是在创建该过程的用户环境中检查权限。但是,如果某用户拥有两个存储过程,并且第一个过程调用第二个过程,则在第二个过程中不进行 EXECUTE 权限检查。
示例
A. 使用 EXECUTE 传递单个参数
showind 存储过程需要参数 (@tabname),它是一个表的名称。下面这个例子执行 showind 存储过程,以 titles 为参数值。
说明 showind 存储过程只是用来作为一个例子,pubs 数据库并没有此过程。
EXEC showind titles
在执行过程中变量可以显式命名:
EXEC showind @tabname = titles
如果这是 isql 脚本或批处理中第一个语句,则 EXEC 语句可以省略:
showind titles
-或-
showind @tabname = titles
B. 使用多个参数与一个输出参数
这个例子执行 roy_check 存储过程,传递三个参数。第三个参数 @pc 是输出参数。过程执行完后,返回变量可以从变量 @percent 得到。
说明 roy_check 存储过程只是用作举例,pubs 数据库中并没有此过程。
DECLARE @percent int
EXECUTE roy_check 'BU1032', 1050, @pc = @percent OUTPUT
SET Percent = @percent
C.使用带一个变量的 EXECUTE 'tsql_string' 语句
这个例子显示 EXECUTE 语句如何处理动态生成的、含有变量的字符串。这个例子创建 tables_cursor 游标来保存所有用户定义表 (type = U) 的列表。
说明 此例子只用作举例。
DECLARE tables_cursor CURSOR
FOR
SELECT name FROM sysobjects WHERE type = 'U'
OPEN tables_cursor
DECLARE @tablename sysname
FETCH NEXT FROM tables_cursor INTO @tablename
WHILE (@@FETCH_STATUS <> -1)
BEGIN
/* A @@FETCH_STATUS of -2 means that the row has been deleted.
There is no need to test for this because this loop drops all
user-defined tables. */.
EXEC ('DROP TABLE ' + @tablename)
FETCH NEXT FROM tables_cursor INTO @tablename
END
PRINT 'All user-defined tables have been dropped from the database.'
DEALLOCATE tables_cursor
D.使用带远程存储过程的 EXECUTE 语句
这个例子在远程服务器 SQLSERVER1 上执行 checkcontract 存储过程,在 @retstat 中保存返回状态,说明运行成功或失败。
DECLARE @retstat int
EXECUTE @retstat = SQLSERVER1.pubs.dbo.checkcontract '409-56-4008'
E. 使用带扩展存储过程的 EXECUTE 语句
下例使用 xp_cmdshell 扩展存储过程列出文件扩展名为 .exe 的所有文件的目录。
USE master
EXECUTE xp_cmdshell 'dir *.exe'
F. 使用带一个存储过程变量的 EXECUTE 语句
这个例子创建一个代表存储过程名称的变量。
DECLARE @proc_name varchar(30)
SET @proc_name = 'sp_who'
EXEC @proc_name
G. 使用带 DEFAULT 的 EXECUTE 语句
这个例子创建了一个存储过程,过程中第一个和第三个参数为默认值。当运行该过程时,如果调用时没有传递值或者指定了默认值,这些默认值就会赋给第一个和第三个参数。注意 DEFAULT 关键字有多种使用方法。
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'proc_calculate_taxes' AND type = 'P')
DROP PROCEDURE proc_calculate_taxes
GO
-- Create the stored procere.
CREATE PROCEDURE proc_calculate_taxes (@p1 smallint = 42, @p2 char(1),
@p3 varchar(8) = 'CAR')
AS
SELECT *
FROM mytable
proc_calculate_taxes 存储过程可以以多种组合方式执行:
EXECUTE proc_calculate_taxes @p2 = 'A'
EXECUTE proc_calculate_taxes 69, 'B'
EXECUTE proc_calculate_taxes 69, 'C', 'House'
EXECUTE proc_calculate_taxes @p1 = DEFAULT, @p2 = 'D'
EXECUTE proc_calculate_taxes DEFAULT, @p3 = 'Local', @p2 = 'E'
EXECUTE proc_calculate_taxes 69, 'F', @p3 = DEFAULT
EXECUTE proc_calculate_taxes 95, 'G', DEFAULT
EXECUTE proc_calculate_taxes DEFAULT, 'H', DEFAULT
EXECUTE proc_calculate_taxes DEFAULT, 'I', @p3 = DEFAULT
sql server 中的自定义函数应该如何调用?
Create function 函数名(参数)2 Returns 返回值数据类型3 [with {Encryption | Schemabinding }]4 [as]5 begin6 SQL语句(return变量)7 End 8 注:Schemabinding将函数绑定到它引用的对象上(注:函数一旦绑定,则不能删除、修改,除非删除绑定)View Code
表值函数-内嵌函数:
1 create function 函数名(参数)2 returns table 3 [with {Encryption | Schemabinding }]4 as 5 return(一条SQL语句)View Code
表值函数-多语句函数:
1 create function 函数名(参数)2 returns 表变量名 table (表变量定义)3 [with {Encryption | Schemabinding }]4 as 5 begin6 SQL语句7 endView Code
下面介绍使用方法,使用前先创建几个表用于测试,表如下:
1 CREATE TABLE [dbo].[Classes]( 2 [ID] [int] IDENTITY(1,1) NOT NULL primary key, 3 [ClassName] [nvarchar](50) NOT NULL, 4 [CreateTime] [datetime] NOT NULL 5 ); 6 7 CREATE TABLE [dbo].[Students]( 8 [ID] [int] IDENTITY(1,1) NOT NULL primary key, 9 [Name] [nvarchar](50) NOT NULL,10 [ClassId] [int] NOT NULL,11 [Age] [int] NOT NULL,12 [CreateTime] [datetime] NOT NULL13 );14 15 CREATE TABLE [dbo].[Courses](16 [ID] [int] IDENTITY(1,1) NOT NULL primary key,17 [Name] [nvarchar](50) NOT NULL,18 [Credit] [float] NOT NULL19 );20 21 CREATE TABLE [dbo].[StuScores](22 [ID] [int] IDENTITY(1,1) NOT NULL primary key,23 [StuId] [int] NOT NULL,24 [CourseId] [int] NOT NULL,25 [Score] [int] NOT NULL26 );View Code
例子如下:
1 --标量函数:返回某个班级的人数 2 create function F_GetSomeClassStuCount(@classId int) 3 returns int 4 as 5 begin 6 declare @rtnCount int 7 select @rtnCount=count(*) from Students where ClassId=@classId 8 return @rtnCount 9 end;10 11 select dbo.F_GetSomeClassStuCount(1);12 13 --表值函数-内嵌函数:返回某个班级的人员信息 注意此处不需begin-end包裹14 create function F_GetSomeClassStruInfo(@classId int)15 returns table16 as 17 return (select * from Students where ClassId=@classId);18 19 select * from dbo.F_GetSomeClassStruInfo(1);20 21 --表值函数-多语句函数:返回某个学生的成绩22 create function F_GetSomStuScore(@stuName nvarchar(50))23 returns @tmpTb table(24 StuName nvarchar(50),25 CourseName nvarchar(50),26 Score int27 )28 as29 begin30 insert into @tmpTb31 select s.Name as StuName,c.Name as CourseName,ss.Score32 from StuScores ss33 left join Students s on ss.StuId=s.ID34 left join Courses c on ss.CourseId=c.ID35 where s.Name=@stuName36 return37 end;38 39 select * from F_GetSomStuScore(‘杨过‘)View Code
sqlserver自定义函数的创建与调用
标签:
sql server 中的自定义函数应该如何调用?
Create function 函数名(参数)2 Returns 返回值数据类型3 [with {Encryption | Schemabinding }]4 [as]5 begin6 SQL语句(return变量)7 End 8 注:Schemabinding将函数绑定到它引用的对象上(注:函数一旦绑定,则不能删除、修改,除非删除绑定)View Code
表值函数-内嵌函数:
1 create function 函数名(参数)2 returns table 3 [with {Encryption | Schemabinding }]4 as 5 return(一条SQL语句)View Code
表值函数-多语句函数:
1 create function 函数名(参数)2 returns 表变量名 table (表变量定义)3 [with {Encryption | Schemabinding }]4 as 5 begin6 SQL语句7 endView Code
下面介绍使用方法,使用前先创建几个表用于测试,表如下:
1 CREATE TABLE [dbo].[Classes]( 2 [ID] [int] IDENTITY(1,1) NOT NULL primary key, 3 [ClassName] [nvarchar](50) NOT NULL, 4 [CreateTime] [datetime] NOT NULL 5 ); 6 7 CREATE TABLE [dbo].[Students]( 8 [ID] [int] IDENTITY(1,1) NOT NULL primary key, 9 [Name] [nvarchar](50) NOT NULL,10 [ClassId] [int] NOT NULL,11 [Age] [int] NOT NULL,12 [CreateTime] [datetime] NOT NULL13 );14 15 CREATE TABLE [dbo].[Courses](16 [ID] [int] IDENTITY(1,1) NOT NULL primary key,17 [Name] [nvarchar](50) NOT NULL,18 [Credit] [float] NOT NULL19 );20 21 CREATE TABLE [dbo].[StuScores](22 [ID] [int] IDENTITY(1,1) NOT NULL primary key,23 [StuId] [int] NOT NULL,24 [CourseId] [int] NOT NULL,25 [Score] [int] NOT NULL26 );View Code
例子如下:
1 --标量函数:返回某个班级的人数 2 create function F_GetSomeClassStuCount(@classId int) 3 returns int 4 as 5 begin 6 declare @rtnCount int 7 select @rtnCount=count(*) from Students where ClassId=@classId 8 return @rtnCount 9 end;10 11 select dbo.F_GetSomeClassStuCount(1);12 13 --表值函数-内嵌函数:返回某个班级的人员信息 注意此处不需begin-end包裹14 create function F_GetSomeClassStruInfo(@classId int)15 returns table16 as 17 return (select * from Students where ClassId=@classId);18 19 select * from dbo.F_GetSomeClassStruInfo(1);20 21 --表值函数-多语句函数:返回某个学生的成绩22 create function F_GetSomStuScore(@stuName nvarchar(50))23 returns @tmpTb table(24 StuName nvarchar(50),25 CourseName nvarchar(50),26 Score int27 )28 as29 begin30 insert into @tmpTb31 select s.Name as StuName,c.Name as CourseName,ss.Score32 from StuScores ss33 left join Students s on ss.StuId=s.ID34 left join Courses c on ss.CourseId=c.ID35 where s.Name=@stuName36 return37 end;38 39 select * from F_GetSomStuScore(‘杨过‘)View Code
sqlserver自定义函数的创建与调用
标签:
求助大牛!C++编程,如何查询数据库中多条记录的多个字段值,并且返回到一个数据块中...急急急!
额。。写个个简单的样列,用的是ODBC,比较直接。使用ADO的话虽然代码少,但是看起来不是很好理解。你可以自己去百度学学~
用到的函数都比较容易理解,我就没多加说明了,如果有不理解的复制函数名百度一下,会有详细的说明的。大概的流程就是这样了~
//包含头文件
#include "windows.h"
#include "sqlext.h"
#pragma comment(lib,"odbc32.lib")
int main(int argc, char* argv[]){
//1.连接数据源(前提是你已经配置好了数据源,我用的sqlserver数据库,怎么配数据源百度一下~很简单的)
//分配环境句柄, 保存一些驱动程序的信息
SQLHENV henv;//环境句柄
SQLRETURN sqlRet;
sqlRet = SQLAllocEnv(&henv);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("分配环境句柄失败!\n");
return -1;
}
//分配连接句柄
SQLHDBC hdbc;//连接句柄
sqlRet = SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("分配连接句柄失败!\n");
return -1;
}
//连接数据源(test是数据库名字,sa 和sa 是用户们和密码,你替换即可)
sqlRet = SQLConnect(hdbc,(SQLCHAR*)"test",strlen("test"),(SQLCHAR*)"sa",2,(SQLCHAR*)"sa",2);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("连接数据源失败!\n");
return -1;
}
//2.执行SQL语句
//准备语句句柄
SQLHSTMT hstmt;
sqlRet = SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("连接语句句柄失败!\n");
return -1;
}
//设置游标类型(参看:http://blog.csdn.net/bichenggui/article/details/5601381)
sqlRet = SQLSetStmtOption(hstmt,SQL_ATTR_CURSOR_TYPE,SQL_CURSOR_KEYSET_DRIVEN);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("设置光标类型失败!\n");
return -1;
}
//执行SQL语句
//直接执行(你替换成你自己的sqlserver语句即可)
sqlRet = SQLExecDirect(hstmt,(SQLCHAR*)"insert into student values('lsk',21)",SQL_NTS);
if (sqlRet != SQL_SUCCESS && sqlRet != SQL_SUCCESS_WITH_INFO)
{
printf("执行SQL语句失败!\n");
return -1;
}
//获取结果集
SQLCHAR value[20]={0};
SQLINTEGER len = 0;
//移动光标(不移动前光标指向结果集第一列的前面)
SQLFetch(hstmt);
//取值(取的是结果集的第一列的值),第二个参数表示取第几列
SQLGetData(hstmt,1,SQL_C_CHAR,value,20,&len);
printf("结果为:%s\n",value);
//假如结果集有多行则再次移动光标即可
SQLFetch(hstmt);
//然后再次取值
SQLGetData(hstmt,1,SQL_C_CHAR,value,20,&len);
//关闭句柄,释放资源
SQLFreeHandle(SQL_HANDLE_STMT, hstmt); //释放语句句柄
SQLDisconnect(hdbc); //断开连接
SQLFreeHandle(SQL_HANDLE_DBC, hdbc); //释放连接句柄
SQLFreeHandle(SQL_HANDLE_ENV, henv); //释放环境句柄
return 0;
}
如何在Delphi中调用oracle的存储过程返回数据集
一.创建包与包体
1.附:建表aaclass为下面作测试用
create table aaclass(CID VARCHAR2(50), CNAME VARCHAR2(50), pnumber NUMBER(10,0) );
INSERT INTO aaclass values('c1', 'cn1', 10 ) ;
INSERT INTO aaclass values('c2', 'cn2', 40 ) ;
INSERT INTO aaclass values('c1', 'cn3', 30 ) ;
commit;
2.建包:
CREATE OR REPLACE PACKAGE PKG_JCCTEST1
AS
type rc_class is ref cursor;
--求p1,p2的和与差,返回的多个值通过游标返回
procere GetSubAndSum2(p1 number,p2 number ,
ResultCursor out rc_class);
--查询满足条件的数据集,返回数据集通过游标返回
procere GetClass2(a in number,ResultCursor out rc_class ) ;
--往表中插一条记录,不返回结果集时,本人用AdoQuery调用(adodataset好象要求必须返回结果集)
procere InsertClass( p_cid varchar2 ,p_cname varchar2 ,
p_pnumber number) ;
end PKG_JCCTEST1;
3.建包体
CREATE OR REPLACE PACKAGE BODY PKG_JCCTEST1
AS
procere GetSubAndSum2(p1 number,p2 number ,
ResultCursor out rc_class)
IS
BEGIN
open ResultCursor for
select p1-p2 as "sum", p1+p2 as "sub" from al;
END ;
procere GetClass2(a in number,ResultCursor out rc_class )
is
begin
open ResultCursor for
select aaclass.* from aaclass where pnumber >a;
end ;
procere InsertClass( p_cid varchar2 ,p_cname varchar2 ,
p_pnumber number)
is
begin
insert into aaclass values(p_cid,p_cname,p_pnumber) ;
-- commit;
end ;
二.在delphi中利用AdoDataSet调用上述第一个存储过程
1.利用AdoConnection1连接数据库(驱动为 oracle Provider for OLE DB),
**并在连接字符串中加入这一节: PLSQLRSet=1; 如下所示:
Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=1
2.在窗体上加AdoDataSet1 指明连接为上述AdoConnection1,下面可以放一个按钮,单击按钮就能调用第一步中创建的包过程,并返回数据集。代码如下所示:
procere TForm1.Button1Click(Sender: TObject);
var
AResult , BResult : integer;
begin
ADODataSet1.Close ;
ADODataSet1.CommandType := cmdText ;
ADODataSet1.Parameters.Clear ;
//***利用call方法调用oracle过程时,参数必须由?来传, 即使你要传的参数为常理
//输出游标的参数不需要指定!!!!!!,本来此函数带三个参数,我们这里只需要传两个参数.
ADODataSet1.CommandText := '{call PKG_JCCTEST1.GetSubAndSum2(?,?)}' ;
//***C 顺序有关,createparam必须放在commandtext赋值语句之后.
// 创建第一个参数,对应call中的第一个?,ftinteger为类型,10为长度,45为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,45);
//创建第二个参数,根据createparameter的顺序 自动与call中的第二个参数对应
ADODataSet1.Parameters.CreateParameter('p2',ftinteger,pdinput,10,4);
//下面调用ADODataSet1 的open方法,返回数据集(对应包过程的游标)
ADODataSet1.Open ;
//根据存储过程,数据集只有一条记录,所以不需要用while do 来遍历数据集,直接取数据了
//此处的字段名根据包过程中的返回游标 对应的字段名来取
//定义的存储过程返回游标如: open ResultCursor for
// select p1-p2 as "sum", p1+p2 as "sub" from al;
//把对应的字段值取出来即可
AResult := ADODataSet1.Fields.FieldByName('sub').Value ;
BResult := ADODataSet1.Fields.FieldByName('sum').Value ;
//显示结果
showmessage(inttostr(AResult)) ;
showmessage(inttostr(BResult)) ;
end;
三.在delphi中利用AdoDataSet调用上述第二个存储过程
还是利用上述的AdoDataSet1来调用第二个存储过程,无需任何改动,加第二个按钮,单击时代码如下:
procere TForm1.Button2Click(Sender: TObject);
begin
ADODataSet1.Close ;
ADODataSet1.CommandType := cmdText ;
ADODataSet1.Parameters.Clear ;
//***利用call方法调用oracle过程时,参数必须由?来传, 即使你要传的参数为常理
//输出游标的参数不需要指定!!!!!!,本来此函数带两个参数,我们这里只需要传一个参数.
ADODataSet1.CommandText := '{call PKG_JCCTEST1.GetClass2(?)}' ;
//***C 顺序有关,createparam必须放在commandtext赋值语句之后.
// 创建第一个参数,对应call中的第一个?,ftinteger为类型,10为长度,20为传入的实参值
ADODataSet1.Parameters.CreateParameter('p1',ftinteger,pdinput,10,20);
//下面调用ADODataSet1 的open方法,返回数据集(对应包过程的游标)
ADODataSet1.Open ;
while not ADODataSet1.Eof do
begin
showmessage('CID : '+string(ADODataSet1.FieldByName('CID').Value) +
'--CNAME :' + string(ADODataSet1.FieldByName('CNAME').Value) +
'--PNUMBER :' + string(ADODataSet1.FieldByName('PNUMBER').Value)
) ;
ADODataSet1.Next ;
end ;
end;
四 利用adoquery调用第三个过程,不返回数据集的
procere TForm1.Button3Click(Sender: TObject);
begin
AdoQuery1.Close ;
AdoQuery1.Parameters.Clear ;
AdoQuery1.SQL.Clear ;
AdoQuery1.SQL.Add('{call PKG_JCCTEST1.GetSubAndSum2(?,?)}') ;
AdoQuery1.Parameters.CreateParameter('P1',ftstring,pdinput, 50,'c11') ;
AdoQuery1.Parameters.CreateParameter('P2',ftstring,pdinput, 50,'cn11') ;
AdoQuery1.Parameters.CreateParameter('P3',ftinteger,pdinput, 50,25) ;
AdoQuery1.ExecSQL ;
end;
五 利用adoquery调用第一个过程,返回数据集的.
procere TForm1.Button4Click(Sender: TObject);
begin
AdoQuery1.Close ;
AdoQuery1.Parameters.Clear ;
AdoQuery1.SQL.Clear ;
AdoQuery1.SQL.Add('{call PKG_JCCTEST1.GetSubAndSum2(?,?)}') ;
AdoQuery1.Parameters.CreateParameter('P1',ftinteger,pdinput, 50,25) ;
AdoQuery1.Parameters.CreateParameter('P2',ftinteger,pdinput, 50,22) ;
AdoQuery1.Open ;
Showmessage(string( AdoQuery1.FieldByName('sub').Value)+'-'+
string( AdoQuery1.FieldByName('sum').Value));
end;
六.关于三层体系的此类问题
两层的解决了,三层类似.
中间层用tadodataset 或tadoquery (+tdatasetprovider),中间层的adoconnection的连接字符串加上plsqlRset=1;
客户端用clientdataset ,大同小异,举例如下:
begin
//调用相应的过程
ClientDataSet1.Close ;
ClientDataSet1.Params.Clear ;
ClientDataSet1.CommandText := '{call PackageName.ProcereName(?,?)}' ;
ClientDataSet1.Params.CreateParam(ftInteger , 'ParamName1', ptInput) ;
ClientDataSet1.Open ;
end ;