2014-04-25 70 views
1

我有Sybase版本10.0.1.3960和'继承'非常大的数据库。我试图授予特权所有表到单个用户。Sybase中的表太多,怎么处理

问题是有很多的表,681表是准确的!

手动写入查询的表太多,所以我生成了sql的主动方式。麻烦的是,编程生成太长。 Sybase具有32767(2^15-1)的限制VARCHAR,并且查询比这更长。我试着定义一个LONG VARCHAR,但我一直收到一个错误。

我在我的绳索末端,我该如何做这项工作?

DECLARE @login VARCHAR(255) 
DECLARE @payload VARCHAR(32765) -- <-- too few characters, too many tables 
SELECT @login = 'myUserLogin' 
SELECT @payload = Result.Payload FROM (
    SELECT LIST(tbl.ApplicableAsset, ';\n') AS 'Payload' 
    From (
    SELECT 'GRANT SELECT ON ' + name + ' TO ' + @login +'' AS 'ApplicableAsset' 
    FROM sysobjects 
    WHERE type='U' 
) AS tbl 
) AS Result 
EXECUTE (@payload) 
+0

写入它作为一个循环为每个表复位@payload。我不是游标的忠实粉丝;但是这可能只是时间来使用它......或者将每个select写出到临时表中,然后从中选择并遍历每一行......这里有很多选项。 – xQbert

+0

我宁愿循环...只是因为它很安静直接向前;) – frlan

+0

你尝试过使用'text'或'long nvarchar'吗? –

回答

0

您可以为这种情况创建一个游标。 在cursot中,您可以生成一个控制长度为字符串的已执行字符串。 例如,如果字符串的长度超过2000 sym,则可以执行此字符串并开始生成新的字符串。

例如,它可以是如:

Decalre Cur Cursor for select One_Grant_Expression from .... 
go 
Open Cur 
Declare @SQLText varchar(8000) 
Declare @OneText varchar(1000) 
fetch Cur into @OneTExt 

while (@@sqlstatus = 0) do 
begin 
    Set @SQLText = @SQLText + @OneText 

if Length(@SQLText) > 2000 

    begin 
     exec (@SQLText) 
     Set @SQLText = '' 
    end 
    fetch Cur into @OneTExt 
end 

If Length(@SQLText) > 0 begin exec (@SQLText) end 

Close Cur 
go