最近抽时间把这个小型管理平台做了完善,目前支持的功能全部通过http+json的接口实现,由于有mysql数据库和httpserver所有对环境依赖程度比较大(建议按照部署文档来操作),demo里面有系统的部署文档和mysql数据库的初始化部署,支持小型并发数在100路左右的视频管理平台,如果开发力量大的可以在这个基础上做二次开发,主要针对用户、资源组和角色等管理,设备管理在5000路左右,视频并发在100路左右(同时100路码流接收和发送)。运行环境是centos7.3 x64系统,mysql采用系统自带的mariadb。
国标28181平台版本已升级(支持多线程处理和接收sip数据、支持BS客户端),新地址:
https://blog.csdn.net/songxiao1988918/article/details/108087792
通过http转国标28181(GB28181-2016)实现动态获取RTSP、RTMP、HLS输出管理平台下载地址如下:
https://download.csdn.net/download/songxiao1988918/10870352
由于上传无法选择0积分下载,没有积分的可以联系我, 联系方式QQ:123011785 ,欢迎大家一起学习!
一、功能介绍:
1、支持国标GB28181平台、国标GB28181 IPC和国标GB28181 NVR设备同时接入 (支持GB28181-2011版本和GB28181-2016版本)
2、支持国标GB28181设备注册和注销,对所有设备进行管理,获取资源 对资源列表进行管理
3、支持国标GB28181的目录订阅,对接收的订阅通知进行处理
4、支持国标GB28181实时视频请求(支持UDP、TCP主动(tcpactive)、TCP被动(tcppassive))
5、支持国标GB28181 PTZ控制
6、支持国标GB28181 录像查询
7、支持国标GB28181 历史视频点播 (支持UDP、TCP主动(tcpactive)、TCP被动(tcppassive))
8、支持国标GB28181 历史视频下载 (支持UDP、TCP主动(tcpactive)、TCP被动(tcppassive))
9、支持对接收的国标实时视频码流和历史视频码流进行管理
10、支持将国标的PS码流转换成ES码流
11、支持丢包打印和断流打印
13、支持RTSP服务和RTSP会话管理
14、支持RTSP客户端 UDP传输和TCP传输
15、支持国标GB28181设备5000路左右的接入管理,支持国标请求视频在100路左右
16、支持国标28181设备和通道写入mysql数据库
17、支持设备的云台PTZ控制,控制类型:上"up",下"down",左"left",右"right",左上"leftup",左下"leftdown",右上"rightup",右下"rightdown",镜头近"zoomin",镜头远"zoomout", 焦距远"focusfar",焦距近"focusnear", 设置预置位"setpos",调预置位"callpos"
18、支持历史视频的查询和历史视频的点播控制
19、支持对国标设备的控制,"record":录像开启和停止-通道id "guard":布放和撤防-报警通道id "reboot":设备重启-设备id "keyfame":强制关键帧-通道id
20、支持对实时视频的图片截图,通过http直接访问图片
21、支持rtmp和hls会话一直保留
22、支持报警消息(设备上线、下线和设备端报警)通过httpclient方式主动通知
23、支持公网和局域网同时存在
24、支持httpserver,接口支持http+json
25、支持设备上线、下线和设备报警通过httpclient通知到指定的httpserver
框架图:
二、使用文档:
如果未安装mariadb,可以使用yum安装,安装mariadb的yum命令:yum -y install mariadb mariadb-server
1.1、设置mysql忽略表名的大小写
[root@localhost ~]# vi /etc/my.cnf.d/server.cnf
在[mysqlld]下加上
lower_case_table_names=1
1.2、设置启动mariadb和开机自启动mariadb数据库
[root@localhost ~]# systemctl start mariadb
[root@localhost ~]# systemctl enable mariadb
1.3、设置mariadb登录的用户名和密码
[root@localhost ~]# mysql -uroot
空格
MariaDB [(none)]> use mysql
MariaDB [mysql]> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');
MariaDB [mysql]> CREATE USER 'root'@'%' IDENTIFIED BY "123456";
MariaDB [mysql]> grant all privileges on *.* to 'root'@'%' identified by '123456';
MariaDB [mysql]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
MariaDB [mysql]> flush privileges;
Mysql数据库初始化完成。
2、初始化数据库表
由于创建表比较少,建议直接使用工具创建表。
将EGEyesForVSS-MariaDB.sql 的内容直接拷贝到工具下,执行相应的语句。
3、Windows准备程序包
4、上传文件
5、检查文件,包括程序和动态库。
1、对所有的*.out和*.sh文件赋予权限
[root@localhost videosvr]# cd /home/videosvr/
[root@localhost videosvr]# chmod 777 *.sh
[root@localhost videosvr]# chmod 777 *.out
[root@localhost videosvr]# chmod 777 objs/*.out
[root@localhost videosvr]# chmod 777 ffmpeg
2、设置环境变量
加载环境变量,运行环境变量脚本:
[root@localhost videosvr]# sh video_setup.sh
注:需要关闭设置环境变量的xhsell窗口,重新打开新的窗口环境变量才会生效。
6、修改配置文件Video.xml
修改配置文件服务器的网卡信息
修改连接mysql数据库的信息
7、脚本方式启动服务
# cd /home/videosvr
# sh video_start.sh
执行成功
3.停止服务:
#cd /home/ videosvr
# sh video_stop.sh
执行成功:
//测试数据-录入服务器信息
insert into SvrTbl(GBServerID, GBServerPort, RtspServerPort, HttpserverPort) values('41010000002008000001', 7060, 7554, 8060);
登录设备网页端修改设备28181注册信息,确保数据库的VSSDevTbl设备id和设备网页端id不一致
4、测试工具 使用 火狐浏览器
获取rtsp的动态地址:
http://222.35.102.22:8060/vss/open_stream/11010000001325000001/1/rtsp
获取返回的视频请求地址:
rtsp://222.35.102.22:7554/Type=1/DevAor=11010000001325000001/sessionid=http-21089079-1545534184-0
获取rtmp的地址:
http://222.35.102.22:8060/vss/open_stream/11010000001325000001/1/rtmp
返回的rtmp地址:
rtmp://222.35.102.22:1935/video/11010000001325000001
获取hls地址
http://222.35.102.22:8060/vss/open_stream/11010000001325000001/1/hls
返回的hls地址为:
http://222.35.102.22:8088/video/11010000001325000001.m3u8
停止视频:
http://222.35.102.22:8060/vss/close_stream/11010000001325000001
实时视频截图功能:
http://222.35.102.22:8060/vss/get_image/11010000001325000001/1
获取图片的地址:
http://222.35.102.22:8088/image/11010000001325000001.jpg
其他功能如ptz控制等方式一致,参考《视频监控平台vss对外协议.txt》。
下面展示一下http+json的接口和mysql数据库表
通道为请求视频的单位,通道id生成方式:
采用20位国标id的方式:
一、通信接口:
视频服务器作为httpserver。
1. 请求视频
字段说明:
"channelid": (字符串) 通道20位编号
"type": (数字) 国标请求视频类型:1:udp 2:tcp主动 3:tcp被动
"videourltype": (字符串) 视频类型:rtsp:返回rtsp地址 rtmp:返回rtmp地址 hls:返回hls地址
"errcode": (数字) 返回值,0表示成功,其他见错误码
"sessionid": (字符串) 会话返回的sessionid
"videourl": (字符串) rtsp地址
请求:
URL: http://122.114.130.9:8088/vss/open_stream/{channelid}/{type}/{videourltype}
HTTP Method: GET
返回:
其中errcode为必填项,errcode小于0表示错误,无数据
{
"errcode":0,
"errdesc":"OK",
"strsessionid":"44030000001320000001",
"videourl":"http://47.92.224.143:8080/video/44030000001320000001.m3u8"
}
2. 停止视频-通过sessionid停止视频 (包含实时视频、历史视频点播、历史视频下载)
字段说明:
"sessionid": (字符串) 会话返回的sessionid
"errcode": (数字) 返回状态值,0表示正常状态,其他见错误码
请求:
URL: http://122.114.130.9:8088/vss/close_stream/{sessionid}
HTTP Method: GET
返回:
其中errcode为必填项,errcode小于0表示错误
{
"errcode":0,
"errdesc":"OK"
}
3. Ptz请求
字段说明:
"channelid": (字符串) 通道20位编号
"ptztype": (字符串) 控制类型:上"up",下"down",左"left",右"right",左上"leftup",左下"leftdown",右上"rightup",右下"rightdown",镜头近"zoomin",镜头远"zoomout",
焦距远"focusfar",焦距近"focusnear", 设置预置位"setpos",调预置位"callpos"
"ptzparam": (数字) 参数,速度范围为0-255,0为停止
请求:
URL: http://122.114.130.9:8088/vss/ptz/{ptztype}/{ptzparam}/{channelid}
HTTP Method: GET
返回:
其中errcode为必填项,errcode小于0表示错误
{"errcode":0,"errdesc":"OK"}
4. 录像查询
字段说明:
"channelid": (字符串) 通道20位编号
"begintime": (字符串) "YYYY-MM-DDTHH:MM:SS": 年月日时分秒; 开始时间,注意不全0
"endtime": (字符串) "YYYY-MM-DDTHH:MM:SS": 年月日时分秒; 结束时间,注意不全0
"data": 录像查询信息
"begintime": (字符串) "YYYY-MM-DDTHH:MM:SS": 年月日时分秒; 开始时间,注意不全0
"endtime": (字符串) "YYYY-MM-DDTHH:MM:SS": 年月日时分秒; 结束时间,注意不全0
"filename": (字符串) 文件名,不一定用,如果根据文件回放才用,根据时间回放不用
"type": (字符串)录像类型 all,time,alarm,manual
请求:
URL: http://122.114.130.9:8088/vss/history_search/{begintime}/{endtime}/{channelid}
HTTP Method: GET
返回:
其中errcode为必填项,errcode小于0表示错误,无数据; 如果errcode等于0,那么数据里面的每项都是必填项
{"errcode":0,"errdesc":"OK","totalsize":3,"onepagesize":3,"totalpage":1,"pageno":1,"count":3,"data":
[
{"channelid":11000000001320000001,"begintime":"2017-09-19T15:13:24","endtime":"2017-09-19T15:38:34","filename":"101101001_0","type":"all"},
{"channelid":11000000001320000001,"begintime":"2017-09-19T15:56:52","endtime":"2017-09-19T16:03:10","filename":"101101001_2","type":"all"},
{"channelid":11000000001320000001,"begintime":"2017-09-19T16:06:42","endtime":"2017-09-19T17:28:55","filename":"101101001_4","type":"all"}
]
}
5. 录像点播/下载
字段说明:
"channelid": (字符串) 通道20位编号
"opttype": (字符串) "vod"点播, "download"下载
"begintime": (字符串) "YYYY-MM-DDTHH:MM:SS": 年月日 时分秒; 开始时间
"endtime": (字符串) "YYYY-MM-DDTHH:MM:SS": 年月日 时分秒; 结束时间
"type": (数字) 国标请求视频类型:1:udp 2:tcp主动 3:tcp被动
返回参数:
"errcode": (数字) 返回状态值,0表示正常状态,其他见错误码
"rtspurl": (字符串) 点播/下载rtsp地址
"sessionid": (字符串) 点播/下载句柄,用于点播控制,关闭(为请求时传入的sessionid)
"filesize": (64位数字) 点播/下载的总大小
请求:
URL: http://122.114.130.9:8088/vss/open_his_stream/{opttype}/{begintime}/{endtime}/{channelid}/{type}
HTTP Method: GET
返回:
其中errcode为必填项,errcode小于0表示错误,无数据; 如果errcode等于0,那么数据里面的每项都是必填项
{
"errccode":0,
"rtspurl":"rtsp://192.168.12.93:9554/Type=2/DevAor=101101001-2017030031-111",
"sessionid":"101101001-2017030031-111"
"filesize":110503259
}
6. 点播控制
字段说明:
"sessionid": (字符串) 点播返回的sessionid句柄
"vodctrltype": (字符串) "play","pause","stop","jump"
"vodctrlparam": (字符串) 0(pause,stop) / 0.125,0.25,0.5,1,2,4,8,16(play) (范围:0-32)/ 从开始时间跳转的秒数(jump)
请求:
URL: http://122.114.130.9:8088/vss/his_stream_ctrl/{sessionid}/{vodctrltype}/{vodctrlparam}
HTTP Method: GET
返回:
其中errcode为必填项,errcode小于0表示错误
{"errccode":0,"errdesc":"OK"}
7. 设备控制
字段说明:
"channelid": (字符串) 通道或者设备20位编号
"devctrltype": (字符串) "record":录像开启和停止-通道id "guard":布放和撤防-报警通道id "reboot":设备重启-设备id "keyfame":强制关键帧-通道id
"param": (字符串) "start"启动,"stop"停止
请求:
URL: http://47.92.224.143:8060/vss/device_ctrl/{devctrltype}/{channelid}/{param}
HTTP Method: GET
返回:
其中errcode为必填项,errcode小于0表示错误
{"errccode":0,"errdesc":"OK"}
8. 实时截图
字段说明:
"channelid": (字符串) 通道20位编号
"type": (数字) 国标请求视频类型:1:udp 2:tcp主动 3:tcp被动
"errcode": (数字) 返回值,0表示成功,其他见错误码
"imageurl": (字符串) 图片的url地址
请求:
URL: http://47.92.224.143:8088/vss/get_image/{channelid}/{type}
HTTP Method: GET
返回:
其中errcode为必填项,errcode小于0表示错误,无数据
{
"errcode":0,
"errdesc":"OK",
"imagetime":"2018-12-18T12:00:00"
"imageurl":"http://47.92.224.143:8080/image/44030000001320000001.jpg"
}
二、报警通知
视频服务器作为httpclient
方法说明:
字段说明:
"channelid": (字符串) 通道20位编号
"alarmtype": (数字) 报警类型(后续根据需求定义)
"alarmtime": (字符串) "YYYY-MM-DDTHH:MM:SS": 年月日 时分秒; 报警时间
"alarmdesc": (字符串) 报警描述
"longitude": (字符串) 经度
"latitude": (字符串) 纬度
请求:
URL: http://122.114.130.9:8088/vssalarm
HTTP Method: POST
Body:
所有字段都为必填项
{"channelid":"11000000001320000001","alarmtype":1,"alarmtime":"2017-09-19T15:13:24","alarmdesc":"fire","longitude":"10.01123","latitude":"20.34221"}
mysql数据库表:
create database EGEyesForVSS;
alter database EGEyesForVSS character set utf8;
/* 使用数据库 */
use EGEyesForVSS;
/* 创建一级设备表 */
create table IF NOT EXISTS VSSDevTbl
(
ID int primary key auto_increment comment '自增ID;',
DevPubID varchar(32) not null unique comment '一级设备账号;',
DevNickname char(128) comment '昵称;',
UserName char(64) comment '用户名;',
Passwd char(64) comment '密码;',
CorpID char(32) comment '设备厂商;',
IP char(16) comment 'IP地址 ;',
Port smallint unsigned comment '端口;',
Alive boolean default 0 comment '注册状态;0-下线;1-上线',
DMarker int default 1 comment '0-未变化;1-增加;2-删除;3-修改;4-已同步,可删除;',
UpdateTime TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP comment '更新时间;'
);
alter table VSSDevTbl comment '创建一级设备表';
/*alter table VSSDevTbl add index idx_DevID(DevPubID);*/
/* 创建二级设备表 */
create table IF NOT EXISTS VSSChannelTbl
(
ID int primary key auto_increment comment '自增ID;',
DevPubID varchar(32) not null comment '一级设备账号;',
Nickname char(128) comment '昵称;',
ChanPubID varchar(32) not null unique comment '二级设备账号;',
Alive boolean default 0 comment '注册状态;0-下线;1-上线',
CorpID char(32) comment '设备厂商;',
Model char(32) comment '设备型号;',
Owner char(32) comment '设备归属;',
CivilCode char(32) comment '行政区域;',
Address char(128) comment '安装地址;',
Parental int default 0 comment '0-没有设备;1-有子设备',
ParentId char(64) comment '父设备;',
IP char(16) comment 'IP地址 ;',
Port smallint unsigned comment '端口;',
Longitude double default 0 comment '经度',
Latitude double default 0 comment '纬度',
Altitude double default 0 comment '海拔',
PTZType int default 0 comment '1-球机;2-半球;3-固定枪机;4-遥控枪机;',
RoomType int default 0 comment '1-室外;2-室内',
DirectionType int default 0 comment '1-东;2-西;3-南;4-北;5-东南;6-东北;7-西南;8-西北;',
StreamType int default 0 comment '0-H264;1-MPEG2;2-MPEG4;3-SVAC;4-3GP;5-H265;',
RealRtspUrl varchar(256) comment '实时视频rtsp地址;' ,
DMarker int default 1 comment '0-未变化;1-增加;2-删除;3-修改;4-已同步,可删除;',
UpdateTime TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP comment '更新时间;'
);
alter table VSSChannelTbl comment '创建二级设备表';
alter table VSSChannelTbl add constraint FK_VSSChannelTbl foreign key (DevPubID) references VSSDevTbl (DevPubID) on delete cascade;
create table IF NOT EXISTS SVRTbl
(
ID int primary key auto_increment comment '自增ID;',
GBServerID varchar(20) not null comment '国标服务器ID;',
IP varchar(16) comment 'IP;',
GBServerPort smallint unsigned comment '国标服务器端口;',
RtspServerPort smallint unsigned comment 'rtsp服务器端口;',
HttpserverPort smallint unsigned comment 'http服务器端口;',
HttpclientSvrIp varchar(16) comment 'http客户端连接服务IP;',
HttpclientSvrPort smallint unsigned comment 'http客户端连接服务端口;',
Active int default 0 comment '运行状态 1开启 0关闭;',
MaxCameraNum int default 0 comment '服务器最大摄像头数量;',
CurrentCameraNum int default 0 comment '服务器当前摄像头数量;',
ServerAlarmNum int default 0 comment '服务器触发警报警戒值;',
UpdateTime TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP comment '更新时间:',
Remark varchar(255) comment'备用字段;'
);
alter table SVRTbl comment '创建服务器配置表';
/* 创建区域组织结构表 */
create table IF NOT EXISTS VSSDomainUnitTbl
(
ID int primary key auto_increment comment '自增ID;',
DevPubID varchar(32) not null comment '一级设备账号;',
DomainPubID char(32) not null unique comment '域名ID;',
Name char(128) comment '名称;',
BusinessGroupID char(32) comment '业务分组ID;',
ParentId char(64) comment '父节点ID;',
UpdateTime TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP comment '更新时间;'
);
alter table VSSDomainUnitTbl comment '创建一级设备表';
alter table VSSDomainUnitTbl add constraint FK_VSSDomainUnitTbl foreign key (DevPubID) references VSSDevTbl (DevPubID) on delete cascade;
/* RTMP会话表 */
create table IF NOT EXISTS VSSRtmpCallTbl
(
ID int primary key auto_increment comment '自增ID;',
ChanPubID varchar(32) not null unique comment '二级设备账号;',
RtmpUrl varchar(256) comment 'rtmp地址;' ,
HlsUrl varchar(256) comment 'hls地址;' ,
Enable smallint DEFAULT 1 comment '是否启用;',
Status int DEFAULT 0 comment'请求视频的状态;',
UpdateTime TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP comment '更新时间;'
);
alter table VSSRtmpCallTbl comment 'RTMP会话表';
alter table VSSRtmpCallTbl add constraint FK_VSSRtmpCallTbl foreign key (ChanPubID) references VSSChannelTbl (ChanPubID) on delete cascade;
/* ********************************************************************************************************** */
/* 创建分页存储过程 */
drop PROCEDURE IF EXISTS VSSDBProcPageView;
delimiter //
CREATE PROCEDURE VSSDBProcPageView
(
IN $TableName VARCHAR(200), /* --表名称 */
IN $FieldList VARCHAR(2000), /* --显示列名 */
IN $PrimaryKey VARCHAR(100), /* --主键 */
IN $Where VARCHAR(1000), /* --查询条件 不含'where'字符 */
IN $Order VARCHAR(1000), /* --排序 不含'order by'字符,如id asc,userid desc,当@SortType=3时生效 */
IN $SortType INT, /* --排序规则 1:正序asc 2:倒序desc 3:多列排序 */
IN $RecorderCount INT, /* --记录总数 0:会返回总记录 */
IN $PageSize INT, /* --分页大小 */
IN $PageIndex INT, /* --页索引 */
OUT $TotalCount INT, /* --总记录数 */
OUT $TotalPageCount INT /* --总分页数 */
)
BEGIN
IF !( ($TableName is null OR $TableName='') OR ($FieldList is null OR $FieldList='') OR ($PrimaryKey is null OR $PrimaryKey='') OR $SortType < 1 OR $SortType >3 OR $RecorderCount < 0 OR $PageSize < 0 OR $PageIndex < 0) THEN
IF ($where is null OR $where='') THEN
SET @new_where1 = ' ' ;
SET @new_where2 = ' WHERE ' ;
ELSE
SET @new_where1 =concat(' WHERE ',$where);
SET @new_where2 =concat(' WHERE ',$where,' AND ');
END IF;
IF $order='' OR $SortType = 1 OR $SortType = 2 THEN
IF $SortType = 1 THEN
SET @new_order =concat(' ORDER BY ',$PrimaryKey,' ASC' );
END IF;
IF $SortType = 2 THEN
SET @new_order =concat(' ORDER BY ',$PrimaryKey,' DESC');
END IF;
ELSE
SET @new_order =concat(' ORDER BY ',$Order);
END IF;
SET @SqlCount = concat('SELECT COUNT(*) into @TotalCount FROM ',$TableName,@new_where1);
SET @SqlCount1 = concat('SELECT CEILING((COUNT(*)+0.0)/',$PageSize,') into @TotalPageCount FROM ',$TableName,@new_where1);
IF $RecorderCount = 0 THEN
PREPARE stmt1 FROM @SqlCount;
EXECUTE stmt1;
set $TotalCount=@TotalCount;
PREPARE stmt1 FROM @SqlCount1;
EXECUTE stmt1;
set $TotalPageCount=@TotalPageCount;
ELSE
set $TotalCount = $RecorderCount;
END IF;
IF $PageIndex > CEILING(($TotalCount+0.0)/$PageSize) THEN
SET $PageIndex = CEILING(($TotalCount+0.0)/$PageSize);
END IF;
IF $PageIndex = 0 or $PageIndex = 1 THEN
SET @Sql=concat('SELECT ',$FieldList,' FROM ',$TableName,@new_where1,@new_order,' limit ',$PageSize);
ELSE
IF $SortType = 1 THEN
SET @Sql=concat('SELECT ',$FieldList,' FROM ',$TableName,@new_where2,$PrimaryKey,' > (SELECT max(',$PrimaryKey,') FROM (SELECT ',$PrimaryKey,' FROM ',$TableName,@new_where1,@new_order,' limit ',$PageSize*($PageIndex-1),' ) AS TMP) ',@new_order,' limit ',$PageSize);
END IF;
IF $SortType = 2 THEN
SET @Sql=concat('SELECT ',$FieldList,' FROM ',$TableName,@new_where2,$PrimaryKey,' < (SELECT MIN(',$PrimaryKey,') FROM (SELECT ',$PrimaryKey,' FROM ',$TableName,@new_where1,@new_order,' limit ',$PageSize*($PageIndex-1),' ) AS TMP) ',@new_order,' limit ',$PageSize);
END IF;
IF $SortType = 3 THEN
IF INSTR($Order,',') > 0 THEN
SET @Sql=concat('SELECT ',$FieldList,' FROM ',$TableName,@new_where2,$PrimaryKey,' NOT IN (SELECT ',$PrimaryKey,' FROM (SELECT ',$PrimaryKey,' FROM ',$TableName,@new_where1,@new_order,' limit ',$PageSize*($PageIndex-1),' ) a)',@new_order,' limit ',$PageSize);
ELSE
SET @new_order =concat(' ORDER BY ',$PrimaryKey,' ASC' );
SET @Sql=concat('SELECT ',$FieldList,' FROM ',$TableName,@new_where2,$PrimaryKey,' > (SELECT max(',$PrimaryKey,') FROM (SELECT ',$PrimaryKey,' FROM ',$TableName,@new_where1,@new_order,' limit ',$PageSize*($PageIndex-1),' ) AS TMP) ',@new_order,' limit ',$PageSize);
END IF;
END IF;
END IF;
Prepare stmt2 from @Sql;
execute stmt2;
END IF;
END;
//
delimiter ;