ORA-12535: TNS: 操作超时

今天在server上安装了10g的数据库,listener都已经配好,客户端也能tnsping,但连接的时候报如下错误:

SQL> connect sys@ocdb as sysdba
请输入口令:
ERROR:
ORA-12535: TNS: 操作超时

Server的OS是windows 2003 enterprise edition

检查了一下windows 2003的防火墙,有开放1521端口,也把 oracle .exe这个程序开放了,怎么还是没办法连接呢?在防火墙中检查了一下 oracle .exe这个选项,发现其指向9i的目录,而我新增加的数据库是10g的!原来是忘记把10g的 oracle .exe文件添加进去了:(

把10g的 oracle .exe文件也添加进去,客户端就可以连上了:) (more…)

ORA-12500: TNS: 监听程序无法启动专用服务器进程

今天因项目需要,在server上安装了9i跟10g两个版本的数据库,接着用9i的listener去监听9i和10g两个版本的数据库,在客户端用OEM或sqlplus去连接10g的数据库时报如下错误:

SQL> connect sys@ocdb as sysdba
请输入口令:
ERROR:
ORA-12500: TNS: 监听程序无法启动专用服务器进程

用tnsping是可以ping通的。

查了相关资料,大概都是讲oracleservice<sid>服务没起来,但我的service却是起来的,后来想了想会不会是用低版本的listener去监听高版本的数据库造成的呢?

做个测试:

当用9i的listener时,可以连接9i的数据库,但不能连接10g的数据库

改成用10g的listener时,两个版本的db都可以连接

所以估计就是由于listener的版本造成的

对COLUMNS_UPDATED()值的解析

COLUMNS_UPDATED()

是一个仅可在 Insert or Update trigger 中调用的方法.
该方法返回 一个 varbinary 的值, 存储了当次Insert 或是 Update 触发器所对应的记录在哪些字段上发生了Inserted or updated.

COLUMNS_UPDATED 函数以从左到右的顺序返回位,最左边的为最不重要的位。最左边的位表示表中的第一列;向右的下一位表示第二列,依此类推。如果在表上创建的触发器包含 8 列以上,则 COLUMNS_UPDATED 返回多个字节,最左边的为最不重要的字节。在 INSERT 操作中 COLUMNS_UPDATED 将对所有列返回 TRUE 值,因为这些列插入了显式值或隐性 (NULL) 值。

可以在触发器主体中的任意位置使用 COLUMNS_UPDATED。

COLUMNS_UPDATED返回值varbinary的算法:

COLUMNS_UPDATED()方法返回的 varbinary,是以每个小节存储8个字段(的修改状态)的方式记录了当前触发器所有列的修改情形.

因此程序以8个字段为一片段来循环处理所有字段.

SET @iVal= SubString(COLUMNS_UPDATED(), @i + 1, 1)

其中@i:

如果前8列,@i =1

9-16列,@i =2

17-24列,@i = 3

以次类推

程序用上面语句将一小节转化为整型.

测试发现:

当@i=1:


当且仅当这一小片只有一个字段有修改时
1,@iVal = 1 = 2^(1-1);
2,@iVal = 2 = 2^(2-1);
3,@iVal = 4 = 2^(3-1);
4,@iVal = 8 = 2^(4-11);
5,@iVal = 16 = 2^(5-1);
6,@iVal = 32 = 2^(6-1);
7,@iVal = 64 = 2^(7-1);
8,@iVal = 128 = 2^(8-1);
而当且仅当1,2个字段有修改时:
@iVal = 2^(1-1) + 2^(2-1) = 3;
而第 2,5,8 三个字段有修改时:
@iVal = 2^(2-1) + 2^(5-1) + 2^(8-1) = 146;

当8个字段都有修改时:
@iVal = 2^(1-1) + 2^(2-1) + … + 2^(8-1) = 255;

也就是说 无论怎样修改,@iVal的值,不外乎是2^n - 1(n>0 and n <9, int)这一数组型成的[和组合](组合时每个数组成员最多出现一次).

因此反过来推算: 对 @iVal 按 2^n分解, 就可算得被修改列的列表.

当@i>1时:

算法跟@i=1时一样,如:

第9列=第1列

第10列=第2列

….

以次类推

用法:

IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
{ comparison_operator } column_bitmask [ ...n ]

其中:

bitwise_operator

是用于比较运算的位运算符。

updated_bitmask

是整型位掩码,表示实际更新或插入的列。例如,表 t1 包含列 C1、C2、C3、C4 和 C5。

假定表 t1 上有 UPDATE 触发器,若要检查列 C2、C3 和 C4 是否都有更新,指定值 14;

若要检查是否只有列 C2 有更新,指定值 2。

comparison_operator

是比较运算符。使用等号 (=) 检查 updated_bitmask 中指定的所有列是否都实际进行了更新。

使用大于号 (>) 检查 updated_bitmask 中指定的任一列或某些列是否已更新。

column_bitmask

是要检查的列的整型位掩码,用来检查是否已更新或插入了这些列。

举例:

下例测试影响 Northwind.dbo.Customers 表中的第 3、第 5 或第 9 列的更新。
USE Northwind
DROP TRIGGER  tr1
GO
CREATE TRIGGER tr1 ON Customers
FOR UPDATE AS
   IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))
      + power(2,(5-1)))
      AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1)))
      )
   PRINT 'Columns 3, 5 and 9 updated'
GO

UPDATE Customers
   SET ContactName=ContactName,
      Address=Address,
      Country=Country
GO

如何Audit表的栏位被谁更新

问题:

Sql server数据库中一table的一个栏位每天会被update,如何查能查到是哪个程序做的?

SQL Server中可用sql trace去跟踪,但只能跟踪目前的session,所以只能写一Trigger去记录当时的情况(对于 oracle 来说可以用logminer去分析归档日志来实现,当然也可以写Trigger去实现),测试如下:

创建测试表并添加测试数据:

CREATE TABLE TR_TEST

(Id INT,

FullName VARCHAR(20)

)

INSERT INTO TR_TEST

VALUES(1,’BrightWen’)

INSERT INTO TR_TEST

VALUES(2,’HONGSU’)

创建Log表:

CREATE TABLE TR_TESTLOG

(LogDate DATETIME,

AuditType VARCHAR(6),

HostName VARCHAR(128),

AppName VARCHAR(250),

Value VARCHAR(20)

)

现在我要稽核栏位FullName被修改的情况:

CREATE TRIGGER TR_Audit ON TR_TEST

FOR UPDATE

AS

IF UPDATE(FullName) AND @@ROWCOUNT > 0

BEGIN

INSERT TR_TESTLOG
SELECT GETDATE(),’Old’,HOST_NAME(),APP_NAME(),FullName
FROM Deleted
INSERT TR_TESTLOG
SELECT GETDATE(),’New’,HOST_NAME(),APP_NAME(),FullName
FROM INSERTED

END

测试:

UPDATE TR_TEST SET FullName = ‘HONGSU1′ WHERE ID =2

SELECT * FROM TR_TESTLOG

LogDate AuditType HostName AppName Value
———————— ——— ———– —————— ———————- ——————–
2006-01-19 14:08:12.080 Old BRIGHTWEN SQL Query Analyzer HONGSU
2006-01-19 14:08:12.090 New BRIGHTWEN SQL Query Analyzer HONGSU1

Oracle工具篇之Tkprof

Tkprof工具可用来格式化sql trace产生的文件,让你更容易看懂trace的内容

用法:

tkprof tracefile outputfile [explain= ] [table= ] [print= ] [insert= ] [sys= ] [sort= ]

参数说明:

tracefile:你要分析的trace文件

outputfile:格式化后的文件

explain=user/password@connectstring

table=schema.tablename

这两个参数是一起使用的,通过连接数据库对在trace文件中出现的每条sql语句查看执行计划,并将之输出到outputfile中

注意,该table必须是数据库中不存在的,如果存在会报错 (more…)

Oracle工具篇之Oradba

在%ORACLE_HOME%\Database下有一个Oradba.exe文件,该文件是让你在本机的本地用户和组中添加ORA_DBA组及把你当前登陆的用户添加进这个组中:

D:\ oracle \ora92\database>oradba

这时你到:计算机管理>本地用户和组,可发现新增加了ORA_DBA组并把你当前登陆帐号天加了进去

Windows下如何删除N天前的归档文件

ITPUB上的问题:

归档日志放到远程主机上,在远程主机要进行定期清理,每天清理半个月前的日志,linux实现很简单,dos命令怎么搞啊?

方法一:

conn sys/ oracle as sysdba
set feedback off
set pagesize 0
set heading off
set verify off
set linesize 100
set trimspool on
spool d:\archive\delete_archivedlog.bat
select ‘del ‘ ||name||”from v$archived_log where completion_time<trunc(sysdate-15) and completion_time>trunc(sysdate-17) and name!= ’standby’;
spool off;
exit

然后将bat文件传送到远程主机每天执行 (more…)

Oracle工具篇之Oradim

创建例程:
-NEW -SID sid | -SRVC 服务 [-INTPWD 口令] [-MAXUSERS 数量] [-STARTMODE a|m] [-PFILE 文件] [-TIMEOUT 秒]

编辑例程:
-EDIT -SID sid [-NEWSID sid] [-INTPWD 口令] [-STARTMODE auto|manual] [-PFILE 文件名] [-SHUTMODE a|i|n] [-SHUTTYPE srvc|inst|srvc,inst] [-TIMEOUT 秒]

删除例程:
-DELETE -SID sid | -SRVC 服务名称

启动服务和例程:
-STARTUP -SID sid [-USRPWD 口令] [-STARTTYPE srvc|inst|srvc,inst] [-PFILE 文件名]

关闭服务和例程:
-SHUTDOWN -SID sid [-USRPWD 口令] [-SHUTTYPE srvc|inst|srvc,inst] [-SHUTMODE a | i | n] (more…)

强制修改字符集

昨天一同事在修改数据库字符集时出现如下问题:

SQL> ALTER DATABASE CHARACTER SET ZHS16CGB231280;

ALTER DATABASE CHARACTER SET ZHS16CGB231280

*

ERROR at line 1:ORA-12712: new character set must be a superset of old character set

它原来的字符集是:al32utf8

出现这个错误是 oracle 只支持从子集到超集的转变

那有什么方法可进行强制转换呢?可以使用如下指令:

alter database character set INTERNAL_USE ZHS16CGB231280

该指令会跳过子集与超集的检验,当然强制转换可能会造成数据的损坏,要谨慎使用!!

关于字符集更详细的信息可参考eygle的文章:

http://www.eygle.com/index-special.htm

关于授权

昨天一朋友问我 oracle 中如何授权的问题,如下:

请教个问题,如何给一个只有select权限的用户指定update或delete某一个table中的某个column的权限?

如:我现在有个用户user1,在建该用户的时候他只有select 的权限,但我现在有个temp_table ,其中的name栏授权给他有update和delete的权限,命令如何下?

oracle 中有两种权限:系统权限和对象权限

对于系统权限,其命令格式如下:

grant system privilege to user [with admin option]

对于对象权限,其命令格式如下:

grant object privilege on object to user [with grant option]

回收权限:

revoke system privilege from user

revoke object privilege on object from user (more…)

  Recent Comments:

    搜索本站

    站点日历

    2月 2012
    « 4    
     12345
    6789101112
    13141516171819
    20212223242526
    272829  

    订阅本站

    文章分类

    最新日志

    热点文章

    日志存档

    常用标签