pb動態腳本
Ⅰ PB中,Dynamic為何而存在
在PB中Dynamic是個很有意思的關鍵字,它允許在PowerScript中動態的調用對象事件或函數,不管這個被調用的事件或函數是否存在,編譯器都能通過(點保護時能保存)。但如果在運行時被調用的事件或函數不存在,則會報錯並取出程序。其實這是PB的一種後期綁定的機制,又叫動態綁定。也就是用了Dynamic的事件或函數直到運行期才知道實際調用的是哪個事件或函數。 當使用以下腳本調用時 w_a mywindow Open(mywindow, "w_a_desc") mywindow.DYNAMIC Set("hello") 程序運行並不會出錯,因為它調用的是w_a_desc的set()函數。Mywindow是一個w_a的變數,但它指向了子類w_a_desc的實例。這是一種典型的裝箱過程,但是在父類w_a的定義中並沒有Set(String)的這個函數,在這里又能被w_a訪問調用。這在程序編寫的有些時候是很方便的。 通常的父類是不允許調用子類的特定函數的,因為這會破壞了父類定義的介面規則。這種方法的使用也影響了代碼的維護,例如一旦改變了子類w_a_desc該函數介面,編譯器並不會在第一時間報出錯誤,而只能到運行時才會出錯。無形時即影響了軟體質量,又給測試增加了測試難度。
Ⅱ 關於PB軟體編寫腳本問題,緊急!
connect using sqlca;
dw_1.settransobject(sqlca)
dw_1.retrieve()
disconnect using sqlca;
Ⅲ 如何在pb腳本當中獲取存儲過程的返回值
本文擬以SYBASE ASE 10.X和11.X資料庫為例,說明如何在PB腳本當中獲取存儲過程的返回值。作為一個存儲過程,其輸出的結果數據可能包括三類:SELECT結果集、RETURN結果、OUTPUT參數。盡管輸出方式眾多,但PB腳本僅僅藉助簡單的FETCH…INTO…語句即可全部獲取這些輸出數據,具體方式如下:
(一)在SYBASE ASE 10.X和11.X資料庫當中創建一個存儲過程deptroster,其有一個輸入參數@deptno、兩個輸出參數@totsal 和 @avgsal、一個RETURN值@number_of_emps以及包含職員姓名和工資的SELECT結果集,可見除了輸入參數@deptno外,其他均為輸出數據,我們需要在PB腳本中獲取,具體代碼如下:
CREATE PROCEDURE deptroster @deptno integer,
@totsal double precision output,
@avgsal double precision output
AS
DECLARE @number_of_emps integer
SELECT emp_fname, emp_lname, salary FROM employee
WHERE dept_id = @deptno
SELECT @totsal = sum(salary),
@avgsal = avg(salary),
@number_of_emps = COUNT(*) FROM employee
WHERE dept_id = @deptno
RETURN @number_of_emps;
二)PB腳本當中我們需要捕獲SELECT結果集、RETURN值和兩個輸出參數,其輸出順序也是按照「SELECT結果集、RETURN值、輸出參數」順序輸出,具體代碼如下:
integer fetchcount = 0
long lDeptno, rc
string fname, lname
double dSalary, dTotSal, dAvgSal
lDeptno = 100
//此處聲明存儲過程名稱
DECLARE deptproc PROCEDURE FOR
@rc = dbo.deptroster
@deptno = :lDeptno,
@totsal = 0 output,
@avgsal = 0 output
USING SQLCA;
//此處開始執行存儲過程
EXECUTE deptproc;
//判斷執行結果
CHOOSE CASE SQLCA.sqlcode
CASE 0
//如果返回0則表示執行成功,至少存在一個SELECT結果集
//藉助LOOP循環開始捕獲這個SELECT結果集
DO
FETCH deptproc INTO :fname, :lname, :dSalary;
CHOOSE CASE SQLCA.sqlcode
CASE 0
fetchcount++
CASE 100
MessageBox ("End of Result Set", &
string (fetchcount) " rows fetched")
CASE -1
MessageBox ("Fetch Failed", &
//此處關閉存儲過程
CLOSE deptproc;
CASE 100
// 如果返回100,則表示沒有返回結果集.
// 此時不需要單獨執行CLOSE語句.
MessageBox ("Execute Successful", "No result set")
CASE ELSE
//其他情況則表示存儲過程執行失敗,提示用戶即可
MessageBox ("Execute Failed", &
string (SQLCA.sqldbcode) " = " &
Ⅳ pb常用的腳本
powerscript
Ⅳ pb如何將動態創建的數據窗口釋放掉
當 們把用powerbuilder(以下簡稱pb)開發的資料庫客戶端應用程序交給用戶後,還需要在用戶的伺服器端的資料庫系統上進行一系列配置工作,如建立業務資料庫和建表、視圖、主鍵、索引等數據對象。只有正確配置了資料庫伺服器上的數據結構,應用程序才能正常運行。通常由經驗豐富的資料庫管理員,使用資料庫系統提供的工具,手工或通過其他輔助工具,來完成資料庫端的配置工作。本文以微軟的sql server 2000為例,介紹用pb開發一個生成業務資料庫及各種業務數據對象的程序,用戶只要運行這個程序,就可以建立資料庫端的數據結構。 程序功能及結構 程序的主要功能是建立客戶應用程序運行時需要的業務資料庫和在新建立的業務資料庫上建立數據對象。 程序的輸入信息通過4個單行編輯文本框獲得: ●sle_database:新建立的資料庫名稱; ●sle_datafile:新建資料庫所用的數據文件; ●sle_logfile:新建資料庫所用的日誌文件; ●sle_script:建立資料庫中的數據對象所用的腳本文件。 完成程序功能的兩個按鈕分別為:cb_create 用於建立資料庫;cb_table用於在新建的資料庫中建立表、主鍵等數據對象。 在兩個輸出窗口中輸出結果:dw_database 用於顯示新建的資料庫名稱及數據文件;dw_objects用於顯示通過cb_table按鈕建立的數據對象。 具體實現 考慮到對於一個特定的應用,在系統分析階段就已經確定資料庫所需要的數據空間、日誌空間的大小等一些系統物理信息,不會等到程序運行時由用戶確定,所以這些信息不需要用戶輸入。資料庫的名稱一般來說也是固定的,用戶輸入的資料庫名稱(sle_database),可用來檢查資料庫系統中是否已經有同名的資料庫。數據文件和邏輯文件的物理位置和名稱,由用戶根據伺服器上的磁碟空間空閑情況輸入(sle_datafile、sle_logfile),程序中給出了初始值,指定的文件位置是sql server通常的數據文件存放位置。 1.建立數據對象的腳本文件(sle_script) 該文件是普通的文本文件類型,其內容由建立表、主鍵等數據對象的數據定義語言(ddl)組成,其語法符合資料庫系統的規則。例如,腳本test.sql內容為建立兩個帶有主鍵的表: create table xz_tj_all ( gxjg char(4) not null, nian smallint not null, yue tinyint not null, bz1 tinyint not null, bz2 tinyint not null, a1 integer , a2 integer , a3 integer , primary key (gxjg, nian, yue, bz1, bz2) ) create table xz_tj_4_1 ( gxjg char(4) not null, nian smallint not null, yue tinyint not null, bz1 tinyint not null, bz2 tinyint not null, a1 integer , primary key (gxjg, nian, yue, bz1, bz2) ) 2.窗口的open事件 應用程序只用到一個窗口(w_create_database),在其open事件中,對兩個全局事務對象進行創建,並利用其中的一個事務對象(tr_sql)與系統資料庫(master)進行連接。此時還沒有進行業務資料庫的創建工作,業務資料庫不存在,所以不能在這里進行與新建業務資料庫的連接。w_create_database 的open事件腳本如下: //創建與master系統資料庫相連接的事務對象 tr_sql = create transaction tr_sql.dbms =「mss microsoft sql server 6.x」 tr_sql.database = 「master」 //資料庫系統管理員 tr_sql.logpass = 「sa」 //伺服器名 tr_sql.servername = 「station4」 //系統管理員口令 tr_sql.logid = 「sa」 tr_sql.autocommit = false tr_sql.dbparm = 「」 //連接到master系統資料庫 connect using tr_sql; if tr_sql.sqlcode <> 0 then messagebox (「資料庫連接錯誤」,「不能連接到sql server資料庫master。請確認sql server資料庫是否啟動。~n~r」 + 「錯誤信息:」+ tr_sql.sqlerrtext) return end if //從系統表sysdatabases中檢索資料庫信息 dw_database.settransobject(tr_sql); //創建與新建業務資料庫相連接的事務對象 tr_newbase = create transaction tr_newbase.dbms =「mss microsoft sql server 6.x」 tr_newbase.logpass =「sa」 tr_newbase.servername =「station4」 tr_newbase.logid =「sa」 tr_newbase.autocommit = false tr_newbase.dbparm =「」 3.cb_create按鈕的單擊事件 根據業務需要,這里創建的數據文件和日誌文件的初始大小為100mb,最大值為200mb,增量為20mb。按鈕cb_create根據輸入參數構造動態sql語句,創建資料庫。cb_create的clicked事件腳本如下: //資料庫名 string ls_database //數據文件路徑及文件名 string ls_datafile //日誌文件路徑及文件名 string ls_logfile //創建資料庫的sql語句 string ls_mysql //邏輯數據文件名 string ls_logicalfilename //邏輯日誌文件名 string ls_logicallogname setpointer(hourglass!) //取得用戶輸入的資料庫名稱 ls_database = trim(sle_database.text) //取得數據文件位置和名稱 ls_datafile = trim(sle_datafile.text) //取得日誌文件位置和名稱 ls_logfile = trim(sle_logfile.text) ls_logicalfilename = ls_database +「arch1」 ls_logicallogname = ls_database +「archlog1」 tr_sql.autocommit = true //建立資料庫的語句 ls_mysql=「create database 」+ls_database+「on」& +「( name =」+ls_logicalfilename+「,」& +「filename = 『」+ls_datafile+「',」& +「size = 100mb,」& +「maxsize = 200,」& +「filegrowth = 20)」& +「log on 」& +「( name = 」+ls_logicallogname+「,」& +「filename = 『」+ls_logfile+「',」& +「size = 100mb,」& +「maxsize = 200,」& +「filegrowth = 20)」 execute immediate :ls_mysql using tr_sql; tr_sql.autocommit = false //檢索出剛剛建立的資料庫 dw_database.retrieve(ls_database) cb_table.enabled = true setpointer(arrow!) 4.cb_table按鈕的單擊事件 按鈕cb_table從指定的腳本文件(sle_script.text)中讀取內容,構造動態的sql語句,創建數據對象。為簡化程序,對於腳本文件大於32765位元組的情況,本文沒做處理,讀者可用多次讀文件等技術自行處理。 cb_table的clicked事件腳本如下: //創建數據對象前的時間 datetime ldt_create //資料庫名 string ls_database //創建數據對象的sql語句 string ls_sql //存儲腳本文件名 string ls_filename //打開文件的文件號 int li_fileno //文件長度,讀取的文件位元組數 long ll_filelength, ll_number //取得新建的資料庫名稱 ls_database = trim(sle_database.text) if messagebox(「請確認」,「將要在」+ls_database+「資料庫中生成表結構?」, question!,yesno!,2) = 2 then return end if setpointer(hourglass!) //為連接業務資料庫的事務對象設置資料庫值 tr_newbase.database = ls_database connect using tr_newbase; if tr_newbase.sqlcode <> 0 then messagebox (「資料庫連接錯誤」,「不能連接到sql server資料庫:」+ls_database +「。~n~r」+「錯誤信息:」+ tr_newbase.sqlerrtext) return end if //取得建立數據對象的時間,並從系統表sysobjects中提取建立的數據對象 select distinct getdate() into :ldt_create from sysobjects using tr_newbase; //此數據窗口將顯示新建事務對象 dw_objects.settransobject(tr_newbase) //從輸入中取得腳本文件名 ls_filename = trim(sle_script.text) ll_filelength = filelength(ls_filename) //對大於32765位元組的文件不做處理 if ll_filelength > 32765 then messagebox(「」,「腳本文件太大」) disconnect using tr_newbase; return elseif ll_filelength > 0 then //讀取文件內容,執行動態sql語句 li_fileno = fileopen(ls_filename, streammode!) ll_number = fileread(li_fileno, ls_sql) if ll_number > 0 and ll_number <= 32765 then tr_newbase.autocommit = true execute immediate :ls_sql usingtr_newbase; tr_newbase.autocommit = false end if fileclose(li_fileno) else //不能正確讀取文件信息 sle_script.setfocus() sle_script.selecttext(1,len(sle_script.text)) messagebox(「打開腳本文件出錯」,「請輸入正確的表結構腳本文件名稱」) disconnect using tr_newbase; return end if //檢索剛剛建立的數據對象 dw_objects.retrieve(ldt_create) disconnect using tr_newbase; setpointer(arrow!)
Ⅵ PB中,Dynamic為何而存在
但如果在運行時被調用的事件或函數不存在,則會報錯並取出程序。其實這是PB的一種後期綁定的機制,又叫動態綁定。也就是用了Dynamic的事件或函數直到運行期才知道實際調用的是哪個事件或函數。 當使用以下腳本調用時w_a mywindowOpen(mywindow, "w_a_desc")mywindow.DYNAMIC Set("hello") 程序運行並不會出錯,因為它調用的是w_a_desc的set()函數。Mywindow是一個w_a的變數,但它指向了子類w_a_desc的實例。這是一種典型的裝箱過程,但是在父類w_a的定義中並沒有Set(String)的這個函數,在這里又能被w_a訪問調用。這在程序編寫的有些時候是很方便的。 通常的父類是不允許調用子類的特定函數的,因為這會破壞了父類定義的介面規則。這種方法的使用也影響了代碼的維護,例如一旦改變了子類w_a_desc該函數介面,編譯器並不會在第一時間報出錯誤,而只能到運行時才會出錯。無形時即影響了軟體質量,又給測試增加了測試難度。
Ⅶ pb腳本語言
按第一段來說:int n=0 //這個要使用窗口的實例變數,你這是局域變數,被刺clicked後計數器都被清0了,當然無效 select 密碼 into:pw from guanliyuan where 口令=:name and 密碼=:code;這句sql語句也有問題,這些寫法就是用戶名和密碼都要對上才能執行成功,既然都對上了,sql 裡面的into 和下面判斷都沒啥實際意義了不是。 if sle_code.text=trim(pw) then n = n + 1//這句,汗,之前你的讓pw = sle_code.text ,然後現在判斷是不是相等?還有這個錯誤計數器N累加幹嘛,密碼對上了還累加錯誤次數計數器 還有我都不知道一個口令,一個密碼,這兩個概念有區別嘛,我就當是用戶名或者用戶號了你這么寫吧//先把n定義為窗口實例變數
Integer ii_n = 0//登陸按鈕event:clicked
String ls_pw
String ls_name,ls_code
ls_name = sle_name.Text
ls_code = sle_code.TextIF ls_name = ''THEN
MessageBox('提醒','請輸入用戶名和密碼')
RETURN
END IFSELECT 密碼 INTO:ls_pw FROM guanliyuan Where 口令 = :ls_name ;
IF SQLCA.SQLCode = 100 THEN //沒找到用戶
ii_n ++ //錯誤計數器累加
MessageBox('提醒','錯誤的用戶名或密碼') //其實是沒有找到這個用戶名
GOTO Error
END IF
//如果你允許空密碼的話,而你的數據密碼的欄位允許NULL
IF IsNull(ls_pw) THEN ls_pw = ''IF ls_pw <> ls_code //輸入的密碼和資料庫里的密碼對不上
MessageBox('提醒','錯誤的密碼,請重新輸入')
ii_n++
GOTO Error
END IF//排除以上錯誤的情況後肯定密碼對上了
Open(w_denglu_user)
Close(PARENT)
RETURN
Error:
IF ii_n = 3 THEN
MessageBox('提醒','你已達到最大次數,不能登錄')
Close(PARENT)
END IF