
在WINCC和Smart200之间使用Modbus协议进行通讯时,可以通过中间变量实现数据的传输。
具体方法如下:
1 在WINCC中创建一个Tag,并将数据类型设置为DBA类型。
2 在中间件中添加一个媒介,将该媒介的类型设置为Modbus TCP/IP Master。
3 在中间件中创建一个通道,并在通道的属性中配置好Modbus TCP/IP Server的IP地址和端口号。
4 在该通道中添加一个数据点,将该数据点的类型设置为Real类型,并在该数据点的属性中指定Smart200的Modbus地址。
5 在中间件中创建一个变量,将该变量的类型设置为数据库类型,并将其关联到上一步中创建的Tag。
6 在变量的读写属性中,将读取方式设置为"Modbus TCP/IP Master",并设置好Modbus地址。
7 在变量的数据源中,将数据源设置为上一步中创建的数据点。
8 在Smart200中创建一个协议,将该协议的类型设置为Modbus RTU Slave。
9 在该协议中添加一个设备,并在设备的属性中配置好Modbus地址。
10 将该设备与Smart200的内部变量(IN/OUT变量)关联,以便将变量中的数据写入Smart200的该内部变量中。
11 在WINCC中,在需要访问Smart200中的变量时,直接读取中间件中创建的变量即可。
以上就是利用中间变量实现WINCC与Smart200之间使用Modbus协议进行通讯的步骤。具体步骤根据具体情况可以略有不同。
数据库连接代码都一样
$protol = 'mysql:host=localhost;dbname=test';
$username = 'monty';
$passwd = '0818';
$dbh = new PDO($protol, $username, $passwd);
以下是一些测试。注意里面的SQL和for或者foreach语句!
测试1(用key值进行绑定)
$stmt = $dbh->prepare('select from t1 where name=:name');
$params = array();
$params['name'] = 'rentao';
foreach($params
as $k=>$v){
$stmt->bindParam($k, $v);
}
$stmt->execute();
$item = array();
while($row
= $stmt->fetch(PDO::FETCH_ASSOC)){
var_dump($row);
}
$stmt = null;
$dbh = null;
总结
PHP在使用PDO做数据库预编译 *** 作的时候,尽量避免使用limit, order by, group by
做预编译处理。绑定变量我们尽量使用统一标准,要不然都使用“?”,要不然使用“:key”。
有用的命令,我在php51进行测试,测试完了,我通过scp把文件传输到php52服务器上
scp -P9888 indexphp rentao@192168104:/home/rentao
Where子句中的连接顺序
ORACLE采用自下而上的顺序解析WHERE子句
根据这个原理 表之间的连接必须写在其他WHERE条件之前 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾
举例
(低效)select … from table t where t sal > and t jobtype = and < (select count() from table t where t pno = t tno;(高效)select … from table t where < (select count() from table t where t pno = t tno and t sal > and t jobtype = ; Select子句中避免使用
当你想在select子句中列出所有的column时 使用动态SQL列引用 是一个方便的方法
不幸的是 这是一个非常低效的方法
实际上 ORACLE在解析的过程中 会将 依次转换成所有的列名 这个工作是通过查询数据字典完成的 这意味着将耗费更多的时间
减少访问数据库的次数
当执行每条SQL语句时 ORACLE在内部执行了许多工作
解析SQL语句 估算索引的利用率 绑定变量 读数据块等等
由此可见 减少访问数据库的次数 就能实际上减少ORACLE的工作量
举例
题目——我要查找编号为 学生的信息
(低效)select name age gender address from t_student where id = ;select name age gender address from t_student where id = ;(高效)select a name a age a gender a address b name b age b gender b address from t_student a t_student b where a id = and b id = ; 使用Decode函数来减少处理时间
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表
举例
(低效)select count() sum(banace) from table where dept_id = and name like anger% ;select count() sum(banace) from table where dept_id = and name like anger% ;(高效)select count(decode(dept_id XYZ null)) count_ count(decode(dept_id XYZ null)) count_ sum(decode(dept_id dept_id null)) sum_ sum(decode(dept_id dept_id null)) sum_ from table where name like anger% ; 整合简单 无关联的数据库访问
如果你有几个简单的数据库查询语句 你可以把它们整合到一个查询中(即使它们之间没有关系)举例
(低效)select name from table where id = ;select name from table where id = ;select name from table where id = ;(高效)select t name t name t namefrom table t table t table t where t id(+) = and t id(+) = and t id(+) =
注 上面例子虽然高效 但是可读性差 需要量情而定啊![nextpage]
删除重复记录
最高效的删除重复记录方法 ( 因为使用了ROWID)举例
delete from table t where t rowid > (select min(t rowid) from table t where t id = t id) 尽量不要使用having子句 可以考虑用where替换
having只会在检索出所有记录之后才对结果集进行过滤 这个处理需要排序 总计等 *** 作
如果能通过where子句限制记录的数目 那就能减少这方面的开销 [nextpage]
尽量用表的别名
当在SQL语句中连接多个表时 请使用表的别名并把别名前缀于每个Column上
这样一来 就可以减少解析的时间并减少那些由Column歧义引起的语法错误
用exists替代in(发现好多程序员不知道这个怎么用)
在许多基于基础表的查询中 为了满足一个条件 往往需要对另一个表进行联接
在这种情况下 使用exists(或not exists)通常将提高查询的效率
举例
(低效)select … from table t where t id > and pno in (select no from table where name like % ) (高效)select … from table t where t id > and exists (select from table t where t pno = t no and name like % ) 用not exists替代not in
在子查询中 not in子句将执行一个内部的排序和合并
无论在哪种情况下 not in都是最低效的 (因为它对子查询中的表执行了一个全表遍历)
为了避免使用not in 我们可以把它改写成外连接(Outer Joins)或not exists
用exists替换distinct
当提交一个包含一对多表信息的查询时 避免在select子句中使用distinct 一般可以考虑用exists替换举例
(低效)select distinct d dept_no d dept_name from t_dept d t_emp e where d dept_no = e dept_no;(高效)select d dept_no d dept_name from t_dept d where exists (select from t_emp where d dept_no = e dept_no) exists使查询更为迅速 因为RDBMS核心模块将在子查询的条件一旦满足后 立刻返回结果
用表连接替换exists
通常来说 采用表连接的方式比exists更有效率
举例
(低效)select ename from emp e where exists (select from dept where dept_no = e dept_no and dept_cat = W ) SELECT ENAME(高效)select ename from dept d emp e where e dept_no = d dept_no and dept_cat = W ; 避免在索引列上使用is null和is not null避免在索引中使用任何可以为空的列 ORACLE将无法使用该索引
对于单列索引 如果列包含空值 索引中将不存在此记录 对于复合索引 如果每个列都为空 索引中同样不存在此记录 如果至少有一个列不为空 则记录存在于索引中
举例
如果唯一性索引建立在表的A列和B列上 并且表中存在一条记录的A B值为( null) ORACLE将不接受下一条具有相同A B值( null)的记录(插入) 然而如果所有的索引列都为空 ORACLE将认为整个键值为空而空不等于空
因此你可以插入 条具有相同键值的记录 当然它们都是空!
lishixinzhi/Article/program/Oracle/201311/16701
第 章 SQL语句处理的过程 在调整之前我们需要了解一些背景知识 只有知道这些背景知识 我们才能更好的去调整sql语句 本节介绍了SQL语句处理的基本过程 主要包括 · 查询语句处理 · DML语句处理(insert update delete) · DDL 语句处理(create drop alter ) · 事务控制(mit rollback) SQL 语句的执行过程(SQL Statement Execution) 图 概要的列出了处理和运行一个sql语句的需要各个重要阶段 在某些情况下 Oracle运行sql的过程可能与下面列出的各个阶段的顺序有所不同 如DEFINE阶段可能在FETCH阶段之前 这主要依赖你如何书写代码 对许多oracle的工具来说 其中某些阶段会自动执行 绝大多数用户不需要关心各个阶段的细节问题 然而 知道执行的各个阶段还是有必要的 这会帮助你写出更高效的SQL语句来 而且还可以让你猜测出性能差的SQL语句主要是由于哪一个阶段造成的 然后我们针对这个具体的阶段 找出解决的办法 图 SQL语句处理的各个阶段 DML语句的处理 本节给出一个例子来说明在DML语句处理的各个阶段到底发生了什么事情 假设你使用ProC程序来为指定部门的所有职员增加工资 程序已经连到正确的用户 你可以在你的程序中嵌入如下的SQL语句 EXEC SQL UPDATE employees SET salary = salary WHERE department_id = :var_department_id; var_department_id是程序变量 里面包含部门号 我们要修改该部门的职员的工资 当这个SQL语句执行时 使用该变量的值 每种类型的语句都需要如下阶段 · 第 步: Create a Cursor 创建游标· 第 步: Parse the Statement 分析语句· 第 步: Bind Any Variables 绑定变量· 第 步: Run the Statement 运行语句· 第 步: Close the Cursor 关闭游标如果使用了并行功能 还会包含下面这个阶段 · 第 步: Parallelize the Statement 并行执行语句如果是查询语句 则需要以下几个额外的步骤 如图 所示 · 第 步: Describe Results of a Query 描述查询的结果集· 第 步: Define Output of a Query 定义查询的输出数据· 第 步: Fetch Rows of a Query 取查询出来的行下面具体说一下每一步中都发生了什么事情 第 步: 创建游标(Create a Cursor) 由程序接口调用创建一个游标(cursor) 任何SQL语句都会创建它 特别在运行DML语句时 都是自动创建游标的 不需要开发人员干预 多数应用中 游标的创建是自动的 然而 在预编译程序(proc)中游标的创建 可能是隐含的 也可能显式的创建 在存储过程中也是这样的 第 步:分析语句(Parse the Statement) 在语法分析期间 SQL语句从用户进程传送到Oracle SQL语句经语法分析后 SQL语句本身与分析的信息都被装入到共享SQL区 在该阶段中 可以解决许多类型的错误 语法分析分别执行下列 *** 作 l 翻译SQL语句 验证它是合法的语句 即书写正确l 实现数据字典的查找 以验证是否符合表和列的定义l 在所要求的对象上获取语法分析锁 使得在语句的语法分析过程中不改变这些对象的定义l 验证为存取所涉及的模式对象所需的权限是否满足l 决定此语句最佳的执行计划l 将它装入共享SQL区l 对分布的语句来说 把语句的全部或部分路由到包含所涉及数据的远程节点 以上任何一步出现错误 都将导致语句报错 中止执行 只有在共享池中不存在等价SQL语句的情况下 才对SQL语句作语法分析 在这种情况下 数据库内核重新为该语句分配新的共享SQL区 并对语句进行语法分析 进行语法分析需要耗费较多的资源 所以要尽量避免进行语法分析 这是优化的技巧之一 语法分析阶段包含了不管此语句将执行多少次 而只需分析一次的处理要求 Oracle只对每个SQL语句翻译一次 在以后再次执行该语句时 只要该语句还在共享SQL区中 就可以避免对该语句重新进行语法分析 也就是此时可以直接使用其对应的执行计划对数据进行存取 这主要是通过绑定变量(bind variable)实现的 也就是我们常说的共享SQL 后面会给出共享SQL的概念 虽然语法分析验证了SQL语句的正确性 但语法分析只能识别在SQL语句执行之前所能发现的错误(如书写错误 权限不足等) 因此 有些错误通过语法分析是抓不到的 例如 在数据转换中的错误或在数据中的错(如企图在主键中插入重复的值)以及死锁等均是只有在语句执行阶段期间才能遇到和报告的错误或情况 查询语句的处理 查询与其它类型的SQL语句不同 因为在成功执行后作为结果将返回数据 其它语句只是简单地返回成功或失败 而查询则能返回一行或许多行数据 查询的结果均采用表格形式 结果行被一次一行或者批量地被检索出来 从这里我们可以得知批量的fetch数据可以降低网络开销 所以批量的fetch也是优化的技巧之一 有些问题只与查询处理相关 查询不仅仅指SELECT语句 同样也包括在其它SQL语句中的隐含查询 例如 下面的每个语句都需要把查询作为它执行的一部分 INSERT INTO table SELECT UPDATE table SET x = y WHERE DELETE FROM table WHERE CREATE table AS SELECT 具体来说 查询· 要求读一致性· 可能使用回滚段作中间处理· 可能要求SQL语句处理描述 定义和取数据阶段 第 步: 描述查询结果(Describe Results of a Query) 描述阶段只有在查询结果的各个列是未知时才需要 例如 当查询由用户交互地输入需要输出的列名 在这种情况要用描述阶段来决定查询结果的特征(数据类型 长度和名字) 第 步: 定义查询的输出数据(Define Output of a Query) 在查询的定义阶段 你指定与查询出的列值对应的接收变量的位置 大小和数据类型 这样我们通过接收变量就可以得到查询结果 如果必要的话 Oracle会自动实现数据类型的转换 这是将接收变量的类型与对应的列类型相比较决定的 第 步: 绑定变量(Bind Any Variables) 此时 Oracle知道了SQL语句的意思 但仍没有足够的信息用于执行该语句 Oracle 需要得到在语句中列出的所有变量的值 在该例中 Oracle需要得到对department_id列进行限定的值 得到这个值的过程就叫绑定变量(binding variables)此过程称之为将变量值捆绑进来 程序必须指出可以找到该数值的变量名(该变量被称为捆绑变量 变量名实质上是一个内存地址 相当于指针) 应用的最终用户可能并没有发觉他们正在指定捆绑变量 因为Oracle 的程序可能只是简单地指示他们输入新的值 其实这一切都在程序中自动做了 因为你指定了变量名 在你再次执行之前无须重新捆绑变量 你可以改变绑定变量的值 而Oracle在每次执行时 仅仅使用内存地址来查找此值 如果Oracle 需要实现自动数据类型转换的话(除非它们是隐含的或缺省的) 你还必须对每个值指定数据类型和长度 关于这些信息可以参考oracle的相关文档 如Oracle Call Interface Programmer s Guide 第 步: 并行执行语句(Parallelize the Statement ) ORACLE 可以在SELECTs INSERTs UPDATEs MERGEs DELETEs语句中执行相应并行查询 *** 作 对于某些DDL *** 作 如创建索引 用子查询创建表 在分区表上的 *** 作 也可以执行并行 *** 作 并行化可以导致多个服务器进程(oracle server processes)为同一个SQL语句工作 使该SQL语句可以快速完成 但是会耗费更多的资源 所以除非很有必要 否则不要使用并行查询 第 步: 执行语句(Run the Statement) 到了现在这个时候 Oracle拥有所有需要的信息与资源 因此可以真正运行SQL语句了 如果该语句为SELECT查询或INSERT语句 则不需要锁定任何行 因为没有数据需要被改变 然而 如果语句为UPDATE或DELETE语句 则该语句影响的所有行都被锁定 防止该用户提交或回滚之前 别的用户对这些数据进行修改 这保证了数据的一致性 对于某些语句 你可以指定执行的次数 这称为批处理(array processing) 指定执行N次 则绑定变量与定义变量被定义为大小为N的数组的开始位置 这种方法可以减少网络开销 也是优化的技巧之一 第 步: 取出查询的行(Fetch Rows of a Query) 在fetch阶段 行数据被取出来 每个后续的存取 *** 作检索结果集中的下一行数据 直到最后一行被取出来 上面提到过 批量的fetch是优化的技巧之一 第 步: 关闭游标(Close the Cursor) SQL语句处理的最后一个阶段就是关闭游标 DDL语句的处理(DDL Statement Processing) DDL语句的执行不同与DML语句和查询语句的执行 这是因为DDL语句执行成功后需要对数据字典数据进行修改 对于DDL语句 语句的分析阶段实际上包括分析 查找数据字典信息和执行 事务管理语句 会话管理语句 系统管理语句只有分析与执行阶段 为了重新执行该语句 会重新分析与执行该语句 事务控制(Control of Transactions) 一般来说 只有使用ORACLE编程接口的应用设计人员才关心 *** 作的类型 并把相关的 *** 作组织在一起 形成一个事务 一般来说 我门必须定义事务 这样在一个逻辑单元中的所有工作可以同时被提交或回滚 保证了数据的一致性 一个事务应该由逻辑单元中的所有必须部分组成 不应该多一个 也不应该少一个 · 在事务开始和结束的这段时间内 所有被引用表中的数据都应该在一致的状态(或可以被回溯到一致的状态)· 事务应该只包含可以对数据进行一致更改(one consistent change to the data)的SQL语句例如 在两个帐号之间的转帐(这是一个事务或逻辑工作单元) 应该包含从一个帐号中借钱(由一个SQL完成) 然后将借的钱存入另一个帐号(由另一个SQL完成) 这 个 *** 作作为一个逻辑单元 应该同时成功或同时失败 其它不相关的 *** 作 如向一个帐户中存钱 不应该包含在这个转帐事务中 在设计应用时 除了需要决定哪种类型的 *** 作组成一个事务外 还需要决定使用BEGIN_DISCRETE_TRANSACTIO存储过程是否对提高小的 非分布式的事务的性能有作用 lishixinzhi/Article/program/Oracle/201311/18806
以上就是关于wincc与smart200用modbus通讯如何用中间变量全部的内容,包括:wincc与smart200用modbus通讯如何用中间变量、php在5.1.*和5.2.*之间pdo数据库 *** 作中的不同、Oracle中的高效语句等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)