c程序存儲過程
A. 編寫存儲過程的作用是什麼
你會寫程序嗎?存儲過程就是程序,就是語句的集合。有些數據的批量連貫的處理,不好用程序寫,用過程寫會很方便,而且執行效率也高。如果你這些處理的數據是有規律的,或者需要反復處理的,那你就定義過程,然後根據你傳入的參數進行處理。跟程序中的過程沒什麼兩樣。而且還有如下
1.存儲過程可以使得程序執行效率更高、安全性更好,因為過程建立之後 已經編譯並且儲存到資料庫,直接寫sql就需要先分析再執行因此過程效率更高,直接寫sql語句會帶來安全性問題,如:sql注入
2.建立過程不會很耗系統資源,因為過程只是在調用才執行。
3.存儲過程可以用於降低網路流量,存儲過程代碼直接存儲於資料庫中,所以不會產生大量T-sql語句的代碼流量。
4.使用存儲過程使您能夠增強對執行計劃的重復使用,由此可以通過使用遠程過程調用 (RPC) 處理伺服器上的存儲過程而提高性能。RPC 封裝參數和調用伺服器端過程的方式使引擎能夠輕松地找到匹配的執行計劃,並只需插入更新的參數值。
5.可維護性高,更新存儲過程通常比更改、測試以及重新部署程序集需要較少的時間和精力。
6.代碼精簡一致,一個存儲過程可以用於應用程序代碼的不同位置。
7.增強安全性:
a、通過向用戶授予對存儲過程(而不是基於表)的訪問許可權,它們可以提供對特定數據的訪問;
b、提高代碼安全,防止 SQL注入(但未徹底解決,例如,將數據操作語言--DML,附加到輸入參數);
c、SqlParameter 類指定存儲過程參數的數據類型,作為深層次防禦性策略的一部分,可以驗證用戶提供的值類型(但也不是萬無一失,還是應該傳遞至資料庫前得到附加驗證)。
缺點就是:
1、大量的利用過程,會對伺服器壓力比較大。
B. 求大神:C語言如何執行SQL sever的存儲過程
執行帶參數的存儲過程的方法如下:
Exec sp_configure 'allow updates',1 --允許更新系統表。
exec dbo.User_ChangeObjectOwnerBatch 'OldOwner','dbo'
以上是兩個例子。
SQL Server中執行帶參數的存儲過程的方法是:
EXEC 存儲過程名字 '參數1','參數2',數值參數
EXEC 是一個關鍵字。
字元串參數使用單引號括起來,數值參數不需要使用單引號
C. C語言 怎麼 調存儲過程
C語言里沒有存儲過程,只有函數,函數調用有兩種方式
傳值調用(call by value)和傳址調用(call by reference)
例如
f1(x)
{
int a;
a=3*1-1;
f2(x,a);
return a+x;
}
f2(int r,int s)
{
int y;
y=2*r+1;
s=x*r;
r=s-y;
return;
}
f1中調用了f2函數,若第一個參數採用傳值方式(無返回值,即f1中x=3 不變,只是把值傳給f2使用而已)第二個參數採用傳址方式(返回的是s的地址引用,即f1中a的值與f2中s的值相等)若x=3,則a+x=24
D. 如何通過c或c++調用存儲過程
給個例子給你看下:
...
_CommandPtr m_cmdptr;
m_cmdptr.CreateInstance(__uuidof( Command ) );
_ParameterPtr inParam2=NULL;
_ParameterPtr inParam3=NULL;
_ParameterPtr inParam4=NULL;
_ParameterPtr outParam1=NULL;
_ParameterPtr outParam2=NULL;
_ParameterPtr outParam3=NULL;
inParam2.CreateInstance(__uuidof(Parameter));
inParam3.CreateInstance(__uuidof(Parameter));
inParam4.CreateInstance(__uuidof(Parameter));
outParam1.CreateInstance(__uuidof(Parameter));
outParam2.CreateInstance(__uuidof(Parameter));
outParam3.CreateInstance(__uuidof(Parameter));
m_cmdptr->ActiveConnection=m_pConnection;
m_cmdptr->CommandType=adCmdStoredProc;
m_cmdptr->CommandText=_bstr_t("proc_XXX");//存儲過程的名稱
//輸入參數
inParam2=m_cmdptr->CreateParameter(_bstr_t("@P1"),adVarChar,adParamInput,32,_bstr_t(P1));
m_cmdptr->Parameters->Append(inParam2);
inParam3=m_cmdptr->CreateParameter(_bstr_t("@P2"),adVarChar,adParamInput,20,_bstr_t(P2));
m_cmdptr->Parameters->Append(inParam3);
//輸出參數
outParam1=m_cmdptr->CreateParameter("@P4",adInteger,adParamOutput,sizeof(int));
m_cmdptr->Parameters->Append(outParam1);
outParam2=m_cmdptr->CreateParameter("@P5",adInteger,adParamOutput,sizeof(int));
m_cmdptr->Parameters->Append(outParam2);
outParam3=m_cmdptr->CreateParameter(_bstr_t("@P6"),adVarChar,adParamOutput,20,_bstr_t(P6));
m_cmdptr->Parameters->Append(outParam3);
//執行
m_cmdptr->Execute(NULL,NULL,adCmdStoredProc);
//取返回值
long p1=m_cmdptr->Parameters->GetItem("@P4")->Value;
long p2=m_cmdptr->Parameters->GetItem("@P5")->Value;
VARIANT vtP6 =m_cmdptr->Parameters->GetItem("@P6")->Value;
if (vtP6.vt != VT_NULL)
strcpy(tp,(_bstr_t)vtP6);
m_cmdptr.Detach;
E. c程序該怎麼樣調用oracle存儲過程並獲取存
如果已經存在一個存儲過程A(參數);
那麼在存儲過程B中可以直接通過:
values := A(參數);即可實現調用。
備註:values必須在初始化過程中進行定義如: values VARCHAR(30);並且此類型必須與A存儲過程返回參數類型一致。
F. c程序該怎麼樣調用oracle存儲過程並獲取存儲過程中的輸出參數的值
我以前這樣用pro*c 這樣玩的,僅供參考
EXEC SQL EXECUTE
DECLARE
lsid varchar2(60);
lss_this_error_code number;
BEGIN
proctest(:ls_name,lsid); --ls_name 輸入參數 lss_id 輸出
:chId := lsid;-- lsid 輸出返回給C變數chId
END;
END-EXEC;
G. 存儲過程的結構是什麼樣的
CREATE PROCEDURE [擁有者.]存儲過程名[;程序編號]
[(參數#1,…參數#1024)]
[WITH
{RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}
]
[FOR REPLICATION]
AS 程序行
其中存儲過程名不能超過128個字。每個存儲過程中最多設定1024個參數
(SQL Server 7.0以上版本),參數的使用方法如下:
@參數名 數據類型 [VARYING] [=內定值] [OUTPUT]
每個參數名前要有一個「@」符號,每一個存儲過程的參數僅為該程序內部使用,參數的類型除了IMAGE外,其他SQL Server所支持的數據類型都可使用。
[=內定值]相當於我們在建立資料庫時設定一個欄位的默認值,這里是為這個參數設定默認值。[OUTPUT]是用來指定該參數是既有輸入又有輸出值的,也就是在調用了這個存儲過程時,如果所指定的參數值是我們需要輸入的參數,同時也需要在結果中輸出的,則該項必須為OUTPUT,而如果只是做輸出參數用,可以用CURSOR,同時在使用該參數時,必須指定VARYING和OUTPUT這兩個語句。
例子:
CREATE PROCEDURE order_tot_amt @o_id int,@p_tot int output AS
SELECT @p_tot = sum(Unitprice*Quantity)
FROM orderdetails
WHERE ordered=@o_id
例子說明:
該例子是建立一個簡單的存儲過程order_tot_amt,這個存儲過程根據用戶輸入的定單ID號碼(@o_id),由定單明細表 (orderdetails)中計算該定單銷售總額[單價(Unitprice)*數量(Quantity)],這一金額通過@p_tot這一參數輸出給調用這一存儲過程的程序。
Create procere procee_name
[@parameter data_type][output]
[with]{recompile|encryption}
as
sql_statement
解釋:
output:表示此參數是可傳回的
with {recompile|encryption}
recompile:表示每次執行此存儲過程時都重新編譯一次
encryption:所創建的存儲過程的內容會被加密
如:
表book的內容如下
編號 書名 價格
001 C語言入門 $30
002 PowerBuilder報表開發 $52
實例1:查詢表Book的內容的存儲過程
create proc query_book
as
select * from book
go
exec query_book
實例2:
加入一筆記錄到表book,並查詢此表中所有書籍的總金額
Create proc insert_book
@param1 char(10),@param2 varchar(20),@param3 money,@param4 money output
with encryption ---------加密
as
insert book(編號,書名,價格) Values(@param1,@param2,@param3)
select @param4=sum(價格) from book
go
執行例子:
declare @total_price money
exec insert_book '003','Delphi 控制項開發指南',$100,@total_price
print '總金額為'+convert(varchar,@total_price)
go
存儲過程的3種傳回值:
1)、以Return傳回整數
2)、以output格式傳回參數
3)、Recordset
傳回值的區別:
output和return都可在批次程式中用變數接收,而recordset則傳回到執行批次的客戶端中。
實例3:
設有兩個表為Proct,Order,其表內容如下:
Proct
產品編號 產品名稱 客戶訂數
001 鋼筆 30
002 毛筆 50
003 鉛筆 100
Order
產品編號 客戶名 客戶訂金
001 南山區 $30
002 羅湖區 $50
003 寶安區 $4
請實現按編號為連接條件,將兩個表連接成一個臨時表,該表只含編號.產品名.客戶名.訂金.總金額,
總金額=訂金*訂數,臨時表放在存儲過程中
代碼如下:
Create proc temp_sale
as
select a.產品編號,a.產品名稱,b.客戶名,b.客戶訂金,a.客戶訂數* b.客戶訂金 as總金額
into #temptable from Proct a inner join Order b on a.產品編號=b.產品編號
if @@error=0
print 'Good'
else
&n bsp; print 'Fail'
go
H. 如何在VC中調用存儲過程
定義好一個Connection連接,然後再產生一個Command對象,利用Command 對象進行存儲過程調用
_ConnectionPtr m_Conn;
_CommandPtr m_Command
_variant_t vNULL;//定義為無參數
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND
m_Conn.CreateInstance( __uuidof( ADODB::Connection ));//初始化一個連接
m_Command.CreateInstance(__uuidof( ADODB::Command));;//初始化一個Command
m_Conn->Open("Provider=sqloledb;Data Source=yjf;Initial Catalog=pubs;User ID=sa;Password=sa","","",adModeUnknown);//在這里用你直接的Connection連接語句
_bstr_t sp_execstr;
sp_execstr="Exec sp_name";//sp_name為存儲過程名,這句話應該可以在SQL Server中直接執行的
m_Command->ActiveConnection=m_Conn;
m_Command->m_CommandTxt=sp_execstr;
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);
**********************************************************************************
_ConnectionPtr m_pConnection;
_CommandPtr m_pCommand;
//.cpp中在函數中執行
//建立ado連接
HRESULT hr;
hr=m_pConnection.CreateInstance(__uuidof(Connection));
try
{
if(SUCCEEDED(hr))
{
hr=m_pConnection->Open(_bstr_t(L"Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=Viper;Data Source=Viper"),_bstr_t (L"sa"),_bstr_t (L""),adModeUnknown);
}
}
catch(_com_error & err)
{
AfxMessageBox(err.Description(),MB_OK,0);
AfxMessageBox(err.ErrorMessage(),MB_OK,0);
AfxMessageBox("無法連接SQL SERVER 伺服器,程序將退出。請檢查網路設備",MB_OK,0);
exit(0);
}
//執行儲存過程
CString cvar1,cvar2;
int cvar3;
cvar1=」ddd」;
cvar2=」";
cvar3=0;
try
{
m_pCommand.CreateInstance(__uuidof(Command));
m_pCommand->ActiveConnection=app->m_pConnection;
m_pCommand->CommandType=adCmdStoredProc;
m_pCommand->CommandText=_bstr_t(」pr_zs_dzdy」);
_variant_t vvar1,vvar2,vvar3;
vvar1=_variant_t(_bstr_t(cvar1));
vvar2=_variant_t(_bstr_t(cvar2));
vvar3=_variant_t(cvar3);
_ParameterPtr mp_var1,mp_var2,mp_var3;
mp_var1.CreateInstance(__uuidof(Parameter));
mp_var2.CreateInstance(__uuidof(Parameter));
mp_var3.CreateInstance(__uuidof(Parameter));
mp_var1=m_pCommand->CreateParameter
(
_bstr_t(」var1″),
adVarChar,
adParamInput,
3,
vvar1
);
m_pCommand->Parameters->Append(mp_var1);
mp_var2=m_pCommand->CreateParameter
(
_bstr_t(」var2″),
adVarChar,
adParamOutput,
3,
vvar2
);
m_pCommand->Parameters->Append(mp_var2);
mp_var3=m_pCommand->CreateParameter
(
_bstr_t(」var3″),
adIntger,
adParamOutput,
9,
vvar3
);
m_pCommand->Parameters->Append(mp_var3);
_variant_t vNull;
vNull.vt=VT_ERROR;
vNull.scode=DISP_E_PARAMNOTFOUND;
m_pCommand->Execute(&vNull,&vNull,adCmdStoredProc);
cvar2=mp_var2->Value.bstrVal;
cvar3=mp_var3->Value;
}
catch(_com_error &error)
{
MessageBox(error.ErrorMessage(),」ADO錯誤!」);
MessageBox(error.Description(),」ADO錯誤!」);
}
********************************************************************************
如果用ODBC訪問資料庫的話,可參考下列代碼:
CDatabase * pDatabase = new CDatabase;
TRY
{
pDatabase->OpenEx( _T("DSN=ODBCName;UID=***;PWD=***"), CDatabase::noOdbcDialog);
}
CATCH (CDBException, e)
{
delete pDatabase;
return;
}END_CATCH
SQL.Format("exec sp_Name");//有參數的話直接寫再後面
pDatabase->ExecuteSQL(SQL);
pDatabase->Close();
delete pDatabase;
****************************
below is from MSDN,you can find a lot of technical article in MSDN if you search"stored procere and VC"
good luck
Steps To Reproce Behavior
In the SQL Server 7.0 Query Analyzer select the test database Pubs.
Create the following stored procere. This stored procere returns a recordset and an out parameter count.
if exists (select * from sysobjects where id = object_id(N'[dbo].[GetJobs]') and OBJECTPROPERTY(id, N'IsProcere') = 1)
drop proc GetJobs
go
create proc GetJobs @id as int, @count as int [out] as
begin
Select @count = Count(*) from jobs where job_id >@id
Select * from jobs where job_id >@id
end
go
Use VC App Wizard to create a new console application and modify the code as follows:
#include "stdafx.h"
#include "stdio.h"
#import "C:\PROGRA~1\COMMON~1\System\ado\msado15.dll" no_namespace rename ("EOF", "EOF2")
struct InitOle {
InitOle() { ::CoInitialize(NULL); }
~InitOle() { ::CoUninitialize(); }
} _init_InitOle_;
int main(int argc, char* argv[])
{
_variant_t varErr((long)0, VT_ERROR);
_CommandPtr comm(__uuidof(Command));
_ConnectionPtr conn(__uuidof(Connection));
_bstr_t connstr="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=pubs;Data Source=(local)";
conn->Open(connstr, "", "", adConnectUnspecified);
comm->ActiveConnection=conn;
comm->CommandText="GetJobs";
comm->CommandType = adCmdStoredProc ;
comm->Parameters->Refresh();
_variant_t recs;
comm->Parameters->Item[_variant_t((short)1)]->Value= _variant_t((long)5);
_RecordsetPtr rs = comm->Execute(&recs, &vtMissing,adCmdStoredProc);
_variant_t recordcount= comm->Parameters->Item[_variant_t((short)2)]->Value;
printf("recordcount = %li\n", (long)recordcount);
return 0;
}
Change the Datasource, User ID and password in the connection string above.
The recordcount variant that the above code returns is of type VT_NULL rather than the number of records that the stored procere returns.
I. 存儲過程的作用是什麼
你會寫程序嗎?存儲過程就是程序,就是語句的集合。有些數據的批量連貫的處理,不好用程序寫,用過程寫會很方便,而且執行效率也高。如果你這些處理的數據是有規律的,或者需要反復處理的,那你就定義過程,然後根據你傳入的參數進行處理。跟程序中的過程沒什麼兩樣。而且還有如下
1.存儲過程可以使得程序執行效率更高、安全性更好,因為過程建立之後
已經編譯並且儲存到資料庫,直接寫sql就需要先分析再執行因此過程效率更高,直接寫sql語句會帶來安全性問題,如:sql注入
2.建立過程不會很耗系統資源,因為過程只是在調用才執行。
3.存儲過程可以用於降低網路流量,存儲過程代碼直接存儲於資料庫中,所以不會產生大量t-sql語句的代碼流量。
4.使用存儲過程使您能夠增強對執行計劃的重復使用,由此可以通過使用遠程過程調用
(rpc)
處理伺服器上的存儲過程而提高性能。rpc
封裝參數和調用伺服器端過程的方式使引擎能夠輕松地找到匹配的執行計劃,並只需插入更新的參數值。
5.可維護性高,更新存儲過程通常比更改、測試以及重新部署程序集需要較少的時間和精力。
6.代碼精簡一致,一個存儲過程可以用於應用程序代碼的不同位置。
7.增強安全性:
a、通過向用戶授予對存儲過程(而不是基於表)的訪問許可權,它們可以提供對特定數據的訪問;
b、提高代碼安全,防止
sql注入(但未徹底解決,例如,將數據操作語言--dml,附加到輸入參數);
c、sqlparameter
類指定存儲過程參數的數據類型,作為深層次防禦性策略的一部分,可以驗證用戶提供的值類型(但也不是萬無一失,還是應該傳遞至資料庫前得到附加驗證)。
缺點就是:
1、大量的利用過程,會對伺服器壓力比較大。