前段时间,想写一个返回指定数量记录的PROCEDURE,代码如下:
CREATE PROCEDURE GetSomeArticles
@cnt int = 1
AS
SELECT TOP @cnt * FROM Articles
结果发现无法运行,始终有问题,百思不得其解,后来询问了一下老师才知道,SELECT TOP N这里的参数N只能为常量,不能为变量。
如果在程序中直接定义SQL语句,然后执行,是可以达到预期效果的:
int cnt = 10;
string strSQL = "SELECT TOP " + cnt.ToString() + " * FROM Articles";
//我自己写的一个应用了工厂设计模式的操作数据库的类
//封装了N多操作数据库的方法
//并且实现了数据库无关性
//即可以用同样的代码来操作Access、MS SQL SERVER、MySQL
//理论上也可以实现操作Oracle,只是没用过它,所以暂时没实现,呵呵
CommDB db = CreateDB.Create();
//执行数据库操作,返回一个DataSet
DataSet ds = db.ExecSQL(strSQL);
但是我确实有这样的需要,想用存储过程来实现,这可怎么办呢?还好,有动态执行SQL这一说法(其实我也不知道这一说法是否准确,暂且这样称呼吧),于是我们可以这样写存储过程:
CREATE PROCEDURE GetSomeArticles
@cnt int = 1
AS
EXEC ("SELECT TOP " + @cnt + " * FROM Articles")
这样就可以解决SELECT TOP N中那个N只能为常量的问题了^_^
另,在MySQL中要实现类似的功能,可以这样写:
DELIMITER $$
CREATE PROCEDURE `GetSomeArticles`(in cnt int)
BEGIN
set @stmt = concat('SELECT * FROM Articles LIMIT 0, ?');
prepare s1 from @stmt;
set @s1 = cnt;
execute s1 using @s1;
deallocate prepare s1;
END$$
DELIMITER ;
CREATE PROCEDURE GetSomeArticles
@cnt int = 1
AS
SELECT TOP @cnt * FROM Articles
结果发现无法运行,始终有问题,百思不得其解,后来询问了一下老师才知道,SELECT TOP N这里的参数N只能为常量,不能为变量。
如果在程序中直接定义SQL语句,然后执行,是可以达到预期效果的:
int cnt = 10;
string strSQL = "SELECT TOP " + cnt.ToString() + " * FROM Articles";
//我自己写的一个应用了工厂设计模式的操作数据库的类
//封装了N多操作数据库的方法
//并且实现了数据库无关性
//即可以用同样的代码来操作Access、MS SQL SERVER、MySQL
//理论上也可以实现操作Oracle,只是没用过它,所以暂时没实现,呵呵
CommDB db = CreateDB.Create();
//执行数据库操作,返回一个DataSet
DataSet ds = db.ExecSQL(strSQL);
但是我确实有这样的需要,想用存储过程来实现,这可怎么办呢?还好,有动态执行SQL这一说法(其实我也不知道这一说法是否准确,暂且这样称呼吧),于是我们可以这样写存储过程:
CREATE PROCEDURE GetSomeArticles
@cnt int = 1
AS
EXEC ("SELECT TOP " + @cnt + " * FROM Articles")
这样就可以解决SELECT TOP N中那个N只能为常量的问题了^_^
另,在MySQL中要实现类似的功能,可以这样写:
DELIMITER $$
CREATE PROCEDURE `GetSomeArticles`(in cnt int)
BEGIN
set @stmt = concat('SELECT * FROM Articles LIMIT 0, ?');
prepare s1 from @stmt;
set @s1 = cnt;
execute s1 using @s1;
deallocate prepare s1;
END$$
DELIMITER ;