如何从表(Oracle)中获取具有给定 rowid 列表 IN STRING 的记录?
任何人都可以帮我解决 FIXME 问题吗?
-- Task: Get records with given rowid IN STRING from a table.
-- NOTICE: I do not known where the given rowid comes from.
-- OUTPUT 'AAAAB0AABAAAAOhAAA'
SELECT ROWID FROM DUAL;
-- OK, one record
SELECT * FROM DUAL WHERE ROWID IN ('AAAAB0AABAAAAOhAAA');
-- run with no errors, and no records
SELECT INFO_ID FROM TM_INFO_CATALOG WHERE ROWID IN (SELECT ROWID FROM DUAL);
-- ERROR: ORA-01410 invalid ROWID, WHY ?????????? (This is my sql statement)
SELECT INFO_ID FROM TM_INFO_CATALOG WHERE ROWID IN ('AAAAB0AABAAAAOhAAA'); -- FIXME
-- Question: How to check an rowid is exists in a table?
-- The following is my way:
-- FIRST, I need check whether the given rowid is from the table to query.
-- OK, but, low performance, as using function 'ROWIDTOCHAR()' (I think so.)
SELECT 1 FROM TM_INFO_CATALOG WHERE 'AAAAB0AABAAAAOhAAA' IN (SELECT ROWIDTOCHAR(ROWID) FROM TM_INFO_CATALOG);
-- ERROR: ORA-01410
SELECT 1 FROM TM_INFO_CATALOG WHERE 'AAAAB0AABAAAAOhAAA' IN (SELECT ROWID FROM TM_INFO_CATALOG);
-- THEN, select the record using the exist rowid
-- SELECT * from TM_INFO_CATALOG WHERE ROWID = %theGivenRowIdWhichExistInThisTable%
我认为我需要强调这一点:
我只想从表(例如 TABLE_A)中选择记录,如果 rowid 与给定的 rowid 匹配。
当所有给定的rowid都来自TABLE_A(要查询的)时,那就没问题了。
但是,只要一个给定的 rowid 来自其他表(TABLE_B 或 DUAL,例如),就会发生“ORA-01410 invalid ROWID”。我想解决这个问题。
我希望有人可以运行第四个 SQL(或具有相同模式的另一个 SQL),然后给我你的解决方案。 那么,第三条和第四条SQL语句除了一个是SQLID类型而另一个是STRING类型之外,有什么区别呢?如何解决第四条SQL的问题?
Any one can help me to resolve the FIXME ?
-- Task: Get records with given rowid IN STRING from a table.
-- NOTICE: I do not known where the given rowid comes from.
-- OUTPUT 'AAAAB0AABAAAAOhAAA'
SELECT ROWID FROM DUAL;
-- OK, one record
SELECT * FROM DUAL WHERE ROWID IN ('AAAAB0AABAAAAOhAAA');
-- run with no errors, and no records
SELECT INFO_ID FROM TM_INFO_CATALOG WHERE ROWID IN (SELECT ROWID FROM DUAL);
-- ERROR: ORA-01410 invalid ROWID, WHY ?????????? (This is my sql statement)
SELECT INFO_ID FROM TM_INFO_CATALOG WHERE ROWID IN ('AAAAB0AABAAAAOhAAA'); -- FIXME
-- Question: How to check an rowid is exists in a table?
-- The following is my way:
-- FIRST, I need check whether the given rowid is from the table to query.
-- OK, but, low performance, as using function 'ROWIDTOCHAR()' (I think so.)
SELECT 1 FROM TM_INFO_CATALOG WHERE 'AAAAB0AABAAAAOhAAA' IN (SELECT ROWIDTOCHAR(ROWID) FROM TM_INFO_CATALOG);
-- ERROR: ORA-01410
SELECT 1 FROM TM_INFO_CATALOG WHERE 'AAAAB0AABAAAAOhAAA' IN (SELECT ROWID FROM TM_INFO_CATALOG);
-- THEN, select the record using the exist rowid
-- SELECT * from TM_INFO_CATALOG WHERE ROWID = %theGivenRowIdWhichExistInThisTable%
I think I need to emphasize the point:
I just want select the records from a table(such as TABLE_A), if the rowid matches the given rowid.
When all given rowid comes from TABLE_A (which to query), then it is all right.
But, as long as one given rowid comes from other tables (TABLE_B or DUAL, such as), then "ORA-01410 invalid ROWID" occured. I want to FIX this problem.
I wish someone could run the fouth SQL (or annother SQL with the same pattern), then give me your solution.
And, What is the difference between the third and the fourth SQL statement except that one is in SQLID type while the other is in STRING type? HOW TO fix the the fourth SQL's problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
假设您有“Oracle 提供的”格式的 ROWID,它看起来像这样:
Oracle 格式是 Base64 字符串编码。从 Oracle 选择 ROWID 将导致该值的 Base64 显示。
此结构中编码了四部分数据:
格式为:OOOOOO.FFF.BBBBBB.RRR
数据文件编号在数据库中是唯一的。您可以从 DBA_DATA_FILES 视图中检索它。每个数据文件都分为块,dba_extents 表将为您提供记录的段名称和段类型。
Assuming you have the ROWID in its "Oracle presented" format, it looks like this:
The Oracle format is a Base64 string encoding. Selecting a ROWID from Oracle will result in a Base64 display of the value.
Four pieces of data are encoded in this structure:
The format is: OOOOOO.FFF.BBBBBB.RRR
The datafile number is unique in the database. You can retrieve it from the DBA_DATA_FILES view. Each datafile is broken into blocks, and the dba_extents table will give you a segment_name and segment_type for the record.
您可以使用 JOIN
You can use a JOIN
ROWID 是一种特殊的数据类型,而不是字符串。这就是我们需要使用 ROWIDTOCHAR() 函数。
由于 ROWID 标识特定表中的特定行,为什么您希望 DUAL 中的 ROWID 与任何其他表中的任何内容匹配?
ROWID 是访问行的更快方式。但需要将 ROWID 作为字符串处理的情况非常不寻常。更常规的方法是这样的:
但更正常的是使用 SELECT ... FOR UPDATE 语法,它隐式使用 ROWID,无需我们费心。
因此,鉴于您尝试做的事情有点不寻常,我认为您应该更多地解释一下您的目标。这样我们就可以帮助您找到实现这些目标的最佳方法。
ROWIDs are a special data type not a string. That's we need to use the
ROWIDTOCHAR()
function.As the ROWID identifies a specific row in a specific table why would you expect the ROWID from DUAL to match anything in any other table?
ROWID is the faster way of accessing a row. But it is highly unusual to need to wrangle ROWIDs as strings. The more regular way of doing this would be something like:
But even more normal would be to use the SELECT ... FOR UPDATE syntax, which implicitly uses ROWID without us having to bother.
So, given that what you are trying to do is a bit unusual I think you should explain a bit more about your goals. That way we can help you find the best way of achieving them.
只是一个提示:
您写道“我不知道给定的 rowid 来自哪里。”。
那么,DBMS_ROWID.ROWID_OBJECT将为您提供对象的ID(然后您可以在ALL_OBJECTS视图中找到该对象)。
无论如何,尽管没有记录,但每次当您尝试使用一个表中的 rowid 来查询另一表时,您都会收到 ORA-01410 错误。因此,您可以简单地用一些程序代码包装您的查询,例如:
或
Just a hint:
You wrote "I do not known where the given rowid comes from.".
Well, DBMS_ROWID.ROWID_OBJECT will give you id of the object (and then you can find the object in ALL_OBJECTS view).
Anyway, it seems that although it is not documented you will get the ORA-01410 error each time when you try to use rowid from one table in query against another table. So instead of trying to force oracle to change its behaviour, you can simply wrap your query with some procedural code like:
or
听起来您可能正在尝试使用 ROWID 来存储表之间的引用。也许您已将一个表中的 ROWID 存储在另一表中?
如果是这种情况,那么这种做法是不正确的。 ROWID 是物理指针,可以在不通知的情况下更改。我不知道在任何情况下将 ROWID 作为数据存储在任何表中是有用的。
表之间的引用完整性应通过存储唯一标识符(即目标表中定义了UNIQUE 约束的列)来实现。
It sounds like you may be trying to use ROWIDs to store references between tables. Perhaps you've stored the ROWIDs from one table in another table?
If this is the case, this approach is not correct. ROWIDs are physical pointers and can change without notification. I'm not aware of any situation where it is useful to store ROWIDs as data in any table.
Referential integrity between tables should be implemented by storing a unique identifier (i.e. the column(s) from the target table that have a
UNIQUE
constraint defined).