查找联合查询

时间:2017-04-12 06:27:02

标签: union sybase sybase-ase

我正在编写支持不同版本Sybase ASE的代码。我正在使用联合查询,问题是不同版本的Sybase ASE在联合查询中支持不同数量的表。联合查询是动态的,将根据服务器中存在的数据库的数量形成。

有什么方法可以找到特定Sybase ASE支持的最大表数?我现在知道的唯一解决方案是使用查询获取版本并从结果中选择版本号并在代码中相应地设置数字。但这不是一个很好的解决方案。我试过检查是否有任何表存储了这个值,但没有出现。任何人都可以为此提出任何解决方案吗?

4 个答案:

答案 0 :(得分:2)

由于我已在此处重新发布了我的SAP回复,我还会添加更多备注......

  • 这是一个概念证明,回答了如何通过T-SQL获取信息的基本问题;据推测,任何真正想要实施解决方案的人都会(最终)解决各种问题:开销/维护,例如......

  • 设置跟踪文件将需要权限才能执行此操作;哪些权限取决于您是否已启用细化权限(请参阅参考手册中的' set tracefile'命令的注释);您需要决定是否/如何将权限授予其他用户

  • 虽然它是真的你不能重复使用tracefile,你可以为tracefile存在的目录创建一个代理表,然后删除'目录中的tracefile,例如:

create proxy_table tracedir external directory at '/tmp' go delete tracedir where filename = 'my_serverlmiits' go

  • 如果您可以同时运行代理表解决方案的多个副本,那么您显然(?)需要确保为每个会话生成唯一的跟踪文件名称;你可以通过将@@ spid附加到文件名来实现这一点,你也可以添加登录名(suser_name()),kpid(从master..monProcess中选择KPID,其中SPID = @@ spid)等等;您还希望确保在尝试创建之前不存在(例如,删除tracedir,其中filename =' .....&# 39 ;;设置tracefile ...)

  • 您的错误(从代理表中选择时)似乎与在事务隔离级别0中运行的客户端应用程序相关(默认情况下,该表需要表上的唯一索引...不是您和# 39;重新完成针对指向OS文件的代理表);尝试将隔离级别设置为1,或者使用不默认为隔离级别0的客户端应用程序(例如,该示例使用基本的 isql 命令行工具运行良好)

  • 如果要将此解决方案进行生产,那么您可能希望分配一个单独的文件系统,以便任何“逃跑”。跟踪会话不会填满重要的文件系统(例如,/ var,/ tmp,$ SYBASE等)

  • 从生产/安全的角度来看,我可能想要研究在DBA /系统proc(创建为在创建者的权限下执行)中封装大量细节的可能性,以便以确保开发人员无法在“错误”中创建​​跟踪文件。目录......以及开启和开启:控制/安全......

然后......

如果您要这样做 LOT ...并且您只对(联合)查询中的最大表数感兴趣,那么它&# 39; d可能更容易构建一个静态的if / then / else(或case)表达式,使你的ASE版本与几个可能的数字相匹配(参见RobV'帖子)。

让我们面对现实,真的,真的,真的,真的要建立一个超过100个表的查询,更不用说500,1000,更多? [你真的不想尝试调整这样的怪物! YIKES ]实际上,我无法看到为什么你想要生成代理表解决方案只是为了从dbcc serverlimits访问单行时你有什么理由可以实现一个硬盘限制(例如,最多100个表)。

我越是想到这一点,作为一名DBA,我会尽我所能确保你的应用程序无法创建一些怪物,数百个表查询,最终导致我陷入困境dataserver只是因为开发人员无法提出更有效的解决方案。 [并且天堂禁止这种类型的应用程序被推广到一般用户社区,即,我必须处理在我的数据服务器中运行的这个怪物的几十个/几百个副本?!?!?!]

答案 1 :(得分:1)

您可以通过运行'dbcc serverlimits'(首先启用traceflag 3604)来获得此类限制。

直到版本15.7,最大值为256。 在16.0中,这被提升到512。 在16.0 SP01中,这再次被提升到1023。

答案 2 :(得分:0)

我建议您使用SAP支持打开案例/票证,以了解是否存在存储此信息的任何系统表。如果没有,我会实现你提到的繁琐的解决方案,并将监视ASE15.7日志中的以下错误:

CR 805525 -- If you exceed the number of tables in a UNION query you can get a signal 11 in ord_getrowbounds instead of an error message. 

答案 3 :(得分:0)

这是我从SAP社区获得的答案

-- enable trace file for your spid
set tracefile '/tmp/my_serverlimits' for @@spid
go
-- dump dbcc serverlimits output to your tracefile
dbcc serverlimits
go
-- turn off tracing
set tracefile off for @@spid
go
-- enable external file access:
sp_configure 'enable file access',1
go
-- create proxy table pointing at the trace file
create proxy_table dbcc_serverlimits external file at '/tmp/my_serverlimits'
go
-- find our column name ('record' of type varchar(255) in this case)
sp_help dbcc_serverlimits
go
-- extract the desired row; store the 'record' value in a @variable
-- and parse for the desired info ...
select * from dbcc_serverlimits where lower(record) like '%union%'
go

 record
 ------------------------------------------------------------------------
 Max number of user tables overall in a statement using UNIONs      : 512

但这种方法存在一些问题。第一个问题是设置跟踪文件。我将主要每天使用此代码,在Sybase中,我认为我们无法删除或覆盖跟踪文件。第二是关于代理表。必须删除代理表,但可以使用以下代码

IF 
exists (select 1 from 
sysobjects where type = 'U' and name = 'dbcc_serverlimits')

begin
drop table 
dbcc_serverlimits
end
go

当从dbcc_serverlimits表进行选择查询时,会出现最终问题。它抛出以下错误

  

无法执行语句。优化器无法找到唯一的   它可用于扫描表'dbo.dbcc_serverlimits'的索引   cursor'jconnect_implicit_26'。 SQLCODE = 311服务器= ************,   严重性级别= 16,状态= 2,事务状态= 1,行= 1行24

     

从dbcc_serverlimits

中选择*

所有这些命令都必须用程序编写(这就是我的想法)。还有更优雅的解决方案吗?