65.9K
CodeProject 正在变化。 阅读更多。
Home

扩展 SQLCA

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2012年1月20日

CPOL

4分钟阅读

viewsIcon

16268

downloadIcon

94

目标是用一个更健壮的替代品替换 SQLCA。

我们将创建一个简单的电子邮件对象。当然,如果需要,您可以在将来扩展它,但现在,让我们只创建我们需要的功能。

我从创建一个自定义类开始。如果您不熟悉这个过程,请看图 1。

RIK-FIG-1_0.jpg

让我们从一个实例变量开始。

N_cst_mailer Instance Variables
 private mailMessage io_mail_message // The message to send

我将实例变量设置为私有的,所以让我们编写几个函数来填充我们的邮件消息。我们将从 TO 开始。请注意,io_mail_message 包含一个名为 recipient 的对象数组。该对象的一个属性是 recipientType。我们正在寻找 mailTorecipientType!还有其他几种我们不关心的类型。

N_cst_mailer.of_to
 // DESCRIPTION
 // Returns the current TO address
 int li_count, li_max
 li_max = upperBound(io_mail_message.recipient) 
 for li_count = 1 to li_max
 // We are looking for the TO address
 if io_mail_message.recipient[li_count].recipientType = mailTo! then
 return io_mail_message.recipient[1].name // We are done,let's just return
 end if
 next
 return ""

现在让我们做 SET 函数

N_cs_mailer.of_to
 // n_cst_mailer.of_to
 // ARGUMENTS string as_to
 // RETURN VALUE              string 
 // DESCRIPTION
 //
 // Sets the mailTo item and returns the old one
 // 2/4/2011 Rik Brooks
 string ls_retVal
 int li_count, li_max
 ls_retVal = of_to()      // return the old value
 li_max = upperBound(io_mail_message.recipient) 
 for li_count = 1 to li_max
 if io_mail_message.recipient[li_count].recipientType = mailTo! Then
 // Overwrite the existing mailto. 
 io_mail_message.recipient[li_count].name = as_to
 return ls_retVal
 end if
 next
 // We didn't find a mailTo. Give it one now
 li_max ++
 io_mail_message.recipient[li_max].recipientType = mailTo! 
 io_mail_message.recipient[li_max].name = as_to
 return ls_retVal

我们还需要一个 Get 和 Set 来获取主题。

N_cst_mailer.of_subject
 // DESCRIPTION
 // Returns the subject of the message
 return io_mail_message.subject
N_cst_mailer.of_subject
 // ARGUMENTS string as_subject
 // RETURN VALUE  string
 // DESCRIPTION
 // Sets the subject of the message and returns the old subject
 string ls_retVal
 ls_retVal = of_subject()
 io_mail_message.subject = as_subject
 return ls_retVal

现在我们只需要一个 send 函数来发送我们的邮件对象,然后我们就可以测试它了。这个对象可以扩展为一个功能齐全的邮件对象,所以我们不要使用 of_send。让我们为专用函数使用一个特殊名称。我将其命名为 of_sqlca_error_send,因为我要发送一个 sqlca 错误。

N_cst_mailer.of_sqlca_error_send
 // DESCRIPTION
 // Sends the message and returns a status
 string ls_retVal, ls_body
 mailReturnCode lo_return
 ls_retVal = "Success"
lo_return = io_mail_session.mailLogon(mailNewSession!) 
 IF lo_return = mailReturnSuccess! THEN
 if of_to( ) <> "" then
ls_body = "Database Error detected at " + & 
 string(datetime(today(), now()), "MM/DD/YYYY HH:MM")
ls_body += "~n" 
 ls_body += "~n SQLDBCODE: " + string(sqlca.sqldbcode) 
 ls_body += "~n User: " + sqlca.logid
 ls_body += "~n~n" + sqlca.sqlerrtext
 io_mail_message.notetext = ls_body
 lo_return = io_mail_session.mailsend(io_mail_message) 
 choose case lo_return
 case mailReturnFailure! 
 ls_retVal = "Failure" 
 case mailReturnInsufficientMemory! 
 ls_retVal = "Out of memory" 
 case mailReturnDiskFull! 
 ls_retVal = "Out of disk space" 
 case mailReturnTooManySessions! 
 ls_retVal = "Too many mail sessions" 
 case mailReturnTooManyFiles! 
 ls_retVal = "Too many files open" 
 end choose
 end if
 else
 ls_retVal = "Failure to log in to mail server" 
 END IF
 return ls_retVal

现在我们的对象将工作,我很想在这里结束,但就在这里,我有一个机会以一种非人为的方式向您展示多态性。

首先说几句话。我们即将在 PowerBuilder 中实现可选参数。我们将要实现如下所示的内容

Of_sent(To {, message {, subject } } )

这意味着您必须至少将 TO 传递给函数,但您也可以传递消息或消息和主题。它将默认最后两个。查看消息框函数的帮助以查看此方面的一个很好的示例。

这将要求您编写三个函数。我总是从传递所有参数的函数开始。

N_cst_mailer.of_send(to, message, subject) 
 // ARGUMENTS
 //          string as_to - recipient address
 //          string as_message - the body
 //          string as_subject - the subject
 // RETURN VALUE
 // A status
 // DESCRIPTION
 // Sends the message and returns a status
 // 2/5/2011 Rik Brooks
 string ls_retVal, ls_body
 mailReturnCode lo_return
 ls_retVal = "Success" 
 mailSession lo_mail_session
lo_mail_session = create mailSession
 lo_return = lo_mail_session.mailLogon(mailNewSession!) 
 IF lo_return = mailReturnSuccess! THEN
// Set the values in the message object
 of_to(as_to) 
 of_subject( as_subject) 
 io_mail_message.notetext = as_message
lo_return = lo_mail_session.mailsend(io_mail_message) 
 choose case lo_return
 case mailReturnFailure! 
 ls_retVal = "Failure" 
 case mailReturnInsufficientMemory! 
 ls_retVal = "Out of memory" 
 case mailReturnDiskFull! 
 ls_retVal = "Out of disk space" 
 case mailReturnTooManySessions! 
 ls_retVal = "Too many mail sessions" 
 case mailReturnTooManyFiles! 
 ls_retVal = "Too many files open" 
 end choose
 else
 ls_retVal = "Failure to log in to mail server" 
 END IF
 return ls_retVal

现在我默认最后一个参数,在本例中是主题行。请注意,我只需要写一行。我调用我刚编写的函数,但对于最后一个参数,我发送一个默认值。如果您真的想变得花哨,您可以将这些默认值放入 ini 文件或您的数据库中。

N_cst_mailer.of_send(as_to, as_message) 
 // ARGUMENTS
 //          string as_to                              The recipient
 //          string as_body             The body of the message
 // RETURN VALUE              string a status
 // DESCRIPTION
 // The send message with a defaulted subject line
 // 2/5/2011 Rik Brooks
 return of_send(as_to, as_body, "(No Subject)")

最后是最简单的函数形式

N_cst_mailer.of_send(to) 
 // ARGUMENTS
 //          as_to
 // RETURN VALUE
 //          A status
 // DESCRIPTION
 // Sends an email message
 // 2/5/2011 Rik Brooks
 return of_send(as_to, "No body sent", "(No Subject)")

好的,我已经说明了我的观点。您可以使用多态性创建自己的具有可选参数的函数。现在让我们完成本文的主题 - 您的自定义 sqlca。

创建一个新对象。这一个需要是一个标准类(参见图 2)。

RIK-FIG-2_0.jpg

此选择将为您提供一个对话框,询问您需要哪个标准类。在本例中,它是一个事务,如图 3 所示。

RIK-FIG-3_0.jpg

现在我们将有一个带有事务的绘制器。我将它保存为 n_cst_sqlca。只有两个小步骤才能使其工作。首先,我们需要在我们的 dbError 事件中放入一些代码。每当我们的 DataWindow 未捕获到数据库错误时,我们都希望向自己发送一封电子邮件。这是代码

N_cst_sqlca.dberror
 // DESCRIPTION
 // Sends an email when an error happens
n_cst_mailer lo_mailer
 lo_mailer = create n_cst_mailer
 lo_mailer.of_to( "your_address@aol.com") 
 lo_mailer.of_subject( "test") 
 messagebox("", lo_mailer.of_sqlca_error_send( ))

现在我们使用新对象。首先,我们必须告诉 PowerBuilder sqlca 不再是传统的那个,而是我们的新对象。转到您的应用程序对象并查看属性。您会看到一个显示附加属性的按钮。当您单击它时,您会得到图 4。

现在 SQLCA 不再是一个事务;它是一个从事务派生或继承的 n_cst_sqlca(参见图 4)。

RIK-FIG-4_0.jpg

最后一部分是测试我们的 sqlca。创建一个窗口并在其中放置一个按钮。在按钮的单击事件中添加以下代码

W_main.cb_1.clicked()
 // Profile EAS Demo DB V115
 SQLCA.DBMS = "ODBC" 
 SQLCA.AutoCommit = False
 SQLCA.DBParm = "ConnectString='DSN=EAS Demo DB V115;UID=dba;PWD=sql'" 
 connect using sqlca ;
string temp
SELECT "bonus"."no_column"  
 INTO :temp  
 FROM "bonus"  ;

奖金表中没有名为“no_column”的列。这将抛出一个错误。现在,当您运行它时,它将自动发送一封电子邮件,告诉您何时出错以及错误是什么。

Database Error detected at 02/05/2011 05:38
SQLDBCODE: -143
 User:
SQLSTATE = S0002
 [Sybase][ODBC Driver][SQL Anywhere]Column ‘no_column' not found

每次发生数据库错误时,都会自动发生这种情况。您无需进行任何编码,您的用户也不必做任何事情。这就是我们过去所说的“优雅编程”,现在您知道如何做了。

© . All rights reserved.