第一次写MySQL存储过程遇到的关于DELIMITER的问题

第一次写MySQL存储过程遇到的关于DELIMITER的问题
在很久很久以前写过Oracle的存储过程,昨天由于某些特殊的原因导致需要在MySQL中写一些存储过程,只能现学现用了
首先写了一个非常简单的存储过程,但是就是如此简单的过程也报错了,其代码如下:

1
2
3
4
5
 
CREATE PROCEDURE test()
BEGIN
    SELECT 'Hello Word!';                                                               
END

在phpmyadmin及客户端都报错,在phpmyadmin中显示:#1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ” at line 3

显然,程序在第一个分号后面出错了
原因不明,遂google之,找到如下地址:http://www.cnblogs.com/hsqzzzl/archive/2008/02/21/1076646.html
文章作者有说:分隔符是通知MySQL客户端已经输入完成的符号。一直都是用“;”,但是在存储过程中不行,因为存储过程中很多语句都需要用到分号
于是得到如下所示代码

1
2
3
4
5
6
DELIMITER ||
CREATE PROCEDURE test()
BEGIN
    SELECT 'Hello Word!';                              
END ||
DELIMITER ;

如果不想使用DELIMITER,在phpmyadmin中执行命令时,在Delimiter文本框中填写||

另在百度百科中有说明:http://baike.baidu.com/view/3068266.htm
MySQL中delimit命令。
  这个命令与存储过程没什么关系。
  其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了。
  即改变输入结束符。
  默认情况下,delimiter是分号“;”。
  在命令行客户端中,如果有一行命令以分号结束,
  那么回车后,mysql将会执行该命令。
  但有时候,不希望MySQL这么做。因为可能输入较多的语句,且语句中包含有分号。
  默认情况下,不可能等到用户把这些语句全部输入完之后,再执行整段语句。
  因为mysql一遇到分号,它就要自动执行。
  这种情况下,就可以使用delimiter,把delimiter后面换成其它符号,如//或$$。
  此时,delimiter作用就是对整个小段语句做一个简单的封装。
  此命令多用在定义子程序,触发程序等musql自己内嵌小程序中。

邮票面值设计

【问题描述】
【描述 Description 】

  给定一个信封,最多只允许粘贴N张邮票,计算在给定M(N+M<=10)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大max ,使得1~max之间的每一个邮资值都能得到。 例如,N=3,M=2,如果面值分别为1分、4分,则在l分~6分之间的每一个邮资值都能得到(当然还有8分、9分和12分):如果面值分别为1分、3分,则在1分~7分之间的每一个邮资值都能得到。可以验证当N=3,M=2时,7分就是可以得到连续的邮资最大值,所以MAX=7,面值分别为l分、3分。 【样例输入】 共一行,两个整数,分表为N与M的值。 【输入格式 Input Format 】 一行,分别为N,M。 【输出格式 Output Format 】 两行。 第一行为m种邮票的面值,按升序排列,各数之间用一个空格隔开。 第二行为最大值。 【样例输入 Sample Input 】 3 2 【样例输出 Sample Output 】 1 3 MAX=7 算法分析 深搜加DP 栈记录所用邮票的面值 每次面值的搜索的范围为:上一次使用的邮票面值+1 to 上一次连续达到的最大值+1 然后DP,记录达到每个面值用的最少邮票数,不断更新最优解 注意要从第1张邮票开始,否则要出错 【代码】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdio.h>
 
int a[11], ans[11];
int b[1001];
int n, m, max;
 
int dp(int i)
{
       int j, k;
 
       for (j = 1; j < 1001; j++)
              b[j] = 9999;
 
       for (j = 1; j <= i; j++)
              b[a[j]] = 1;
       j = 0;
 
       do
       {
              j++;
 
              for (k = 1; k <= i; k++)
                     if (j > a[k] && b[j - a[k]] + 1 < b[j])
                            b[j] = b[j - a[k]] + 1;
 
       }while (b[j] <= m);
       return j;
}
 
void search(int i)
{
       int j, k;
 
       if (i > n)
       {
              if (dp(i - 1) - 1 > max)
              {
                     for (j = 1; j <= 10; j++)
                            ans[j] = a[j];
                     max = dp(i - 1) - 1;
              }
              return;
       }
       j = dp(i - 1);
 
       for (k = j ; k >= a[i - 1] + 1; k--)
       {
              a[i] = k;
              search(i + 1);
       }
}
 
int main()
{
 
       int i;
       scanf("%d%d", &m, &n);
 
       max = 0;
       a[1] = 1;
       search(2);
 
       for (i = 1; i <= n; i++)
              printf("%d ", ans[i]);
 
       printf("\n");
       printf("MAX=%d\n", max);
       return 0;
}

YII框架中可以使用foreach遍历对象以及可以使用数组形式直接访问对象的原因

YII框架中可以使用foreach遍历对象以及可以使用数组形式直接访问对象的原因
在YII框架的使用过程中,我们可以使用foreach直接遍历findAll等方法返回的对象的属性
为什么呢?其实这与CModel实现的接口相关,接下来我们看下其实现的整个过程
对于一个我们定义的model,它会继承虚类CActiveRecord,CActiveRecord类继承于CModel,如下所示:

1
2
3
4
class special extends CActiveRecord {
}
abstract class CActiveRecord extends CModel{
}

最关键的地方是CModel类实现了IteratorAggregate接口。
而在CModel类中实现的getIterator方法返回的是这个model的所有属性,使用的迭代器是Yii框架实现的CMapIterator,而CMapIterator实现了Iterator接口

1
2
3
4
5
6
7
8
9
10
/**
* Returns an iterator for traversing the attributes in the model.
* This method is required by the interface IteratorAggregate.
* @return CMapIterator an iterator for traversing the items in the list.
*/
public function getIterator()
{
$attributes=$this->getAttributes();
return new CMapIterator($attributes);
}

这些就使得我们可以使用foreach直接遍历findAll等方法返回的对象
关于此迭代器可以参看之前写的关于迭代器的文章:
PHP源码阅读笔记二十四 :iterator实现中当值为flase时无法完成迭代的原因分析

关于IteratorAggregate接口请移步
http://cn.php.net/manual/en/class.iteratoraggregate.php
关于Iterator接口请移步
http://cn.php.net/manual/en/class.iterator.php

同样的道理,
因为CModel实现了ArrayAccess接口,所以可以直接访问以数组的方式访问
关于ArrayAccess接口请移步
http://cn.php.net/manual/en/class.arrayaccess.php