⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 046.htm

📁 Delphi基础知识讲座
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> ━━━━━━━━━━━━━━━━━━━━━</font><font
face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN">   属 性     </font><font
face="Arial"> </font><font face="宋体" lang="ZH-CN"> 属</font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN">性</font><font face="Arial"> </font><font face="宋体"
lang="ZH-CN">表</p>
<p> </font><font face="Arial"> </font><font face="宋体" lang="ZH-CN"> </font><font
face="Arial"> </font><font face="宋体" lang="ZH-CN">─────────────────────</font><font
face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> </font><font face="Arial"> DatabaseName EmployeeDemoDB</p>
<p>IndexFieldName Emp_No</p>
<p></font><font face="宋体" lang="ZH-CN">  </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> </font><font face="Arial"> MasterFields Emp_No</p>
<p>MasterSource EmployeeSource</p>
<p>TableName SALARY_HISTORY</p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> ━━━━━━━━━━━━━━━━━━━━━</p>
<p> </p>
<p>  这两个表之间存在两种关系:</p>
<p>  ●</font><font face="Arial"> </font><font face="宋体" lang="ZH-CN">连接关系</font><font
face="Arial"></p>
<p>EmployeeTable</font><font face="宋体" lang="ZH-CN">的记录变化时,</font><font
face="Arial">SalaryHistoryTable</font><font face="宋体" lang="ZH-CN">的数据要作相应的变化。这种连接关系是通过索引来实现的。</p>
<p>  ●</font><font face="Arial"> </font><font face="宋体" lang="ZH-CN">数据一致性</font><font
face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN">对</font><font face="Arial">EmployeeTable</font><font
face="宋体" lang="ZH-CN">中的</font><font face="Arial">Salary</font><font
face="宋体" lang="ZH-CN">字段的值作修改必须反映到</font><font face="Arial">SalaryHistoryTable</font><font
face="宋体" lang="ZH-CN">中,</font><font face="Arial">SalaryHistoryTable</font><font
face="宋体" lang="ZH-CN">维护的是</font><font face="Arial">Salary</font><font
face="宋体" lang="ZH-CN">变化的历史信息。这种数据一致性要求在本程序中是通过触发器实现的。</p>
<p>  触发器是在</font><font face="Arial">SQL</font><font face="宋体"
lang="ZH-CN">服务器端执行的一段程序,它在服务器端被触发执行完成一定的数据计算任务。</p>
<p>  下面是</font><font face="Arial">InterBase</font><font face="宋体"
lang="ZH-CN">服务器上与</font><font face="Arial">Employee</font><font face="宋体"
lang="ZH-CN">表相关的触发器程序:</p>
<p> </p>
<p></font><font face="Arial">Triggers on Table EMPLOYEE:</p>
<p>SAVE_SALARY_CHANGE, Sequence: 0, Type: AFTER UPDATE, Active AS</font><font
face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">BEGIN</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">IF (old.salary &lt;&gt; new.salary) THEN</p>
<p>INSERT INTO salary_history</p>
<p>(emp_no, change_date, updater_id, old_salary, percent_change)</p>
<p>VALUES (</p>
<p>old.emp_no,</p>
<p>'now',</p>
<p>user,</p>
<p>old.salary,</p>
<p>(new.salary - old.salary) * 100 / old.salary);</p>
<p>END</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p>  因为触发器是相应于</font><font face="Arial">EMPLOYEE</font><font
face="宋体" lang="ZH-CN">表上的数据修改由服务器自动触发执行的,所以在客户应用程序上没有显式的调用。在客户端有打开并显示数据库表内容的程序和当</font><font
face="Arial">SALARY_HISTORY</font><font face="宋体" lang="ZH-CN">表中数据变化时的更新显示的操作。</p>
<p> </p>
<p></font><font face="Arial">procedure TFrmTriggerDemo.FormShow(Sender: TObject);</p>
<p>begin</p>
<p>DmEmployee.EmployeeTable.Open;</p>
<p>DmEmployee.SalaryHistoryTable.Open;</p>
<p>end;</p>
<p> </p>
<p>procedure TDmEmployee.EmployeeTableAfterPost(DataSet: TDataSet);</p>
<p>begin</p>
<p>{ </font><font face="宋体" lang="ZH-CN">一个雇员的薪水变化将触发薪水调整历史记录的变化</font><font
face="Arial">,</p>
<p></font><font face="宋体" lang="ZH-CN">因此,如果</font><font face="Arial">SalaryHistory</font><font
face="宋体" lang="ZH-CN">打开的话,就需要更新显示</font><font face="Arial">
}</p>
<p>with SalaryHistoryTable do if Active then Refresh;</p>
<p>end;</p>
<p> </p>
<p>18.4.2.4 </font><font face="宋体" lang="ZH-CN">存储过程编程</p>
<p> </p>
<p>  存储过程也是</font><font face="Arial">SQL</font><font face="宋体"
lang="ZH-CN">服务器上的一段程序,它接收输入参数,在服务器端执行,并将结果返回客户端,存储过程是必须在客户应用程序中显式调用的。</p>
<p>  对于数据库表中大量记录的统计和函数计算,存储过程是很有用,这样可以将重复性计算任务转换到服务器,提高数据库应用的性能。</p>
<p> </font><font face="Arial"> Delphi</font><font face="宋体" lang="ZH-CN">中有两个部件能操作远程数据库服务器上的存储过程:</font><font
face="Arial">TQuery</font><font face="宋体" lang="ZH-CN">和</font><font face="Arial">TStoredProc</font><font
face="宋体" lang="ZH-CN">。</font><font face="Arial"></p>
<p>1. TQuery</font><font face="宋体" lang="ZH-CN">的存储过程编程</font><font
face="Arial"></p>
<p>CSDEMO</font><font face="宋体" lang="ZH-CN">中演示用</font><font face="Arial">TQuery</font><font
face="宋体" lang="ZH-CN">调用存储过程的窗体是</font><font face="Arial">TFrmQueryProc</font><font
face="宋体" lang="ZH-CN">。</font><font face="Arial"> </p>
</font><font face="宋体" lang="ZH-CN"><p>  </font><font face="Arial">TFrmQueryProc</font><font
face="宋体" lang="ZH-CN">中有两个</font><font face="Arial">TDBGrid </font><font
face="宋体" lang="ZH-CN">部件。</font><font face="Arial">DBGrid1</font><font
face="宋体" lang="ZH-CN">显示</font><font face="Arial">EmployeeTable</font><font
face="宋体" lang="ZH-CN">中的数据。</font><font face="Arial">DBGrid2</font><font
face="宋体" lang="ZH-CN">显示</font><font face="Arial">Project</font><font
face="宋体" lang="ZH-CN">表中的数据。使用存储过程的</font><font
face="Arial">TQuery</font><font face="宋体" lang="ZH-CN">部件名为</font><font
face="Arial">EmployeeProjectsQuery</font><font face="宋体" lang="ZH-CN">,它的作用是建立</font><font
face="Arial">Employee </font><font face="宋体" lang="ZH-CN">表和</font><font
face="Arial">Project </font><font face="宋体" lang="ZH-CN">表的连接,以实现当</font><font
face="Arial">DBGrid1</font><font face="宋体" lang="ZH-CN">中记录改变时,</font><font
face="Arial">DBGrid2</font><font face="宋体" lang="ZH-CN">中的数据作相应的改变。具体的连接任务是由服务器上的存储过程</font><font
face="Arial">Get_Emp_Proj</font><font face="宋体" lang="ZH-CN">完成。下面是</font><font
face="Arial">Get_Emp_Proj</font><font face="宋体" lang="ZH-CN">的程序:</p>
<p> </p>
<p></font><font face="Arial">PROCEDURE Get_Emp_Proj</p>
<p>BEGIN</p>
<p>FOR SELECT proj_id</p>
<p>FROM employee_project</p>
<p>WHERE emp_no = :emp_no</p>
<p>INTO :proj_id</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">DO</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">SUSPEND;</p>
<p>END</p>
<p> </p>
<p>EMP_NO INPUT SMALLINT </p>
<p>PROJ_ID OUTPUT CHAR(5) </p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p>  该过程带两个参数:</p>
<p>  </font><font face="Arial">EMP_NO</font><font face="宋体" lang="ZH-CN">是输入参数,类型是</font><font
face="Arial">SMALLINT.</p>
<p>PROJ_ID</font><font face="宋体" lang="ZH-CN">是输出参数,类型是</font><font
face="Arial">CHAR(5)</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p>  相应地,</font><font face="Arial">EmployeeProjectsQuery</font><font
face="宋体" lang="ZH-CN">的主要属性如下:</p>
<p> </font><font face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN">表</font><font face="Arial">18. 18
EmployeeProjectsQuery</font><font face="宋体" lang="ZH-CN">部件主要属性的取值</font><font
face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN">━━━━━━━━━━━━━━━━━━━━━━━━━━</font><font
face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN">   属 性       属</font><font
face="Arial"> </font><font face="宋体" lang="ZH-CN">性</font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN">值</font><font face="Arial"></p>
<p></font><font face="宋体" lang="ZH-CN"> </font><font face="Arial"> </font><font
face="宋体" lang="ZH-CN"> ──────────────────────────</p>
<p> </font><font face="Arial"> </font><font face="宋体" lang="ZH-CN"> </font><font
face="Arial"> DatabaseName EmployeeDemoDB</p>
<p>Params EMP_No(</font><font face="宋体" lang="ZH-CN">输入参数,</font><font
face="Arial">Smallint</font><font face="宋体" lang="ZH-CN">类型</font><font
face="Arial">)</p>
<p>SQL Select * from</p>
<p>Get_Emp_Proj(:EMP_NO)</p>
<p></font><font face="宋体" lang="ZH-CN">━━━━━━━━━━━━━━━━━━━━━━━━━━</p>
<p> </font><font face="Arial"></p>
<p>TQuery</font><font face="宋体" lang="ZH-CN">部件是在</font><font face="Arial">SQL</font><font
face="宋体" lang="ZH-CN">语句中直接调用存储过程。</p>
<p>  下面是客户端的程序:</p>
<p> </p>
<p></font><font face="Arial">procedure TFrmQueryProc.FormShow(Sender: TObject);</p>
<p>begin</p>
<p>DmEmployee.EmployeeTable.Open;</p>
<p>EmployeeSource.Enabled := True;</p>
<p>with EmployeeProjectsQuery do if not Active then Prepare;</p>
<p>end;</p>
<p> </font><font face="宋体" lang="ZH-CN"></p>
<p>  用</font><font face="Arial">Prepare</font><font face="宋体" lang="ZH-CN">显式地准备</font><font
face="Arial">SQL</font><font face="宋体" lang="ZH-CN">语句,虽非必须,但可以优化</font><font
face="Arial">SQL</font><font face="宋体" lang="ZH-CN">的执行。</p>
<p> </p>
<p></font><font face="Arial">procedure TFrmQueryProc.EmployeeDataChange(Sender: TObject;
Field: TField);</p>
<p>begin</p>
<p>EmployeeProjectsQuery.Close;</p>
<p>EmployeeProjectsQuery.Params[0].AsInteger :=</p>
<p>DmEmployee.EmployeeTableEmp_No.Value;</p>
<p>EmployeeProjectsQuery.Open;</p>
<p> </p>
<p>WriteMsg('Employee ' + DmEmployee.EmployeeTableEmp_No.AsString +</p>
<p>' is assigned to ' + IntToStr(EmployeeProjectsQuery.RecordCount) +</p>
<p>' project(s).');</font><font face="宋体" lang="ZH-CN"></p>
<p></font><font face="Arial">end;</font><font face="宋体" lang="ZH-CN"></p>
<p> </p>
<p>  该事件处理过程与</font><font face="Arial">EmployeeSource</font><font
face="宋体" lang="ZH-CN">的</font><font face="Arial">OnDataChange</font><font
face="宋体" lang="ZH-CN">属性相联。用于当</font><font face="Arial">EmployeeTable</font><font
face="宋体" lang="ZH-CN">数据记录变化时,修正存储过程的输入参数,并执行</font><font
face="Arial">SQL</font><font face="宋体" lang="ZH-CN">语句。</p>
<p>  </font><font face="Arial">2. TStoredProc</font><font face="宋体" lang="ZH-CN">部件的存储过程编程</p>
<p>  </font><font face="Arial">TStoredProc Delphi </font><font face="宋体"
lang="ZH-CN">专门用来使用服务器存储过程的部件。</font><font face="Arial">CSDEMO
</font><font face="宋体" lang="ZH-CN">中演示用</font><font face="Arial">TStoredProc</font><font
face="宋体" lang="ZH-CN">调用存储过程的窗体是</font><font face="Arial">TFrmExecPr</font><font
face="宋体" lang="ZH-CN"></p>
<p>  在程序运行中,当按下</font><font face="Arial">ShipOrder</font><font
face="宋体" lang="ZH-CN">按钮,要求对</font><font face="Arial">ORED_STA_TUS</font><font
face="宋体" lang="ZH-CN">等字段的内容作修改以维护数据库的一致性。字段内容的修改任务由服务器上的存储过程</font><font
face="Arial">SHIP_ORDER</font><font face="宋体" lang="ZH-CN">完成。</font><font
face="Arial">SHIP_ORDE</font><font face="宋体" lang="ZH-CN">的程序如下:</p>
<p> </p>
<p></font><font face="Arial">PROCEDURE SHIP_ORDER</p>
<p>DECLARE VARIABLE ord_stat CHAR(7);</p>
<p>DECLARE VARIABLE hold_stat CHAR(1);</p>
<p>DECLARE VARIABLE cust_no INTEGER;</p>
<p>DECLARE VARIABLE any_po CHAR(8);</p>
<p>BEGIN</p>
<p>SELECT s.order_status, c.on_hold, c.cust_no</p>
<p>FROM sales s, customer c</p>
<p>WHERE po_number = :po_num</p>
<p>AND s.cust_no = c.cust_no</p>
<p>INTO :ord_stat, :hold_stat, :cust_no;</p>
<p>IF (ord_stat = &quot;shipped&quot;) THEN</p>
<p>BEGIN</p>
<p>EXCEPTION order_already_shipped;</p>
<p>SUSPEND;</p>
<p>END</p>
<p>ELSE IF (hold_stat = &quot;*&quot;) THEN</p>
<p>BEGIN</p>
<p>EXCEPTION customer_on_hold;</p>
<p>SUSPEND;</p>
<p>END</p>
<p> </p>
<p>FOR SELECT po_number</p>
<p>FROM sales</p>
<p>WHERE cust_no = :cust_no</p>
<p>AND order_status = &quot;shipped&quot;</p>
<p>AND paid = &quot;n&quot;</p>
<p>AND ship_date &lt; 'NOW' - 60</p>
<p>INTO :any_po</p>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -