'数据库可能尚未激活或可能处于转换中'错误

时间:2009-08-12 14:46:15

标签: sql sql-server tsql sql-server-2000

我有这个重度嵌套的sql语句,在我的sql server 2008 express中运行良好 [下面的代码块]

但是,当我将它移到我们的初步测试服务器(sql server 2000)时,除非我在每个语句的from子句中使用完全解析的表引用,否则它不起作用。我不能这样做,因为数据库名称因现场安装而异。

它给了我这个错误信息:

Msg 913,Level 16,State 8,Line 14 找不到数据库ID 102.数据库可能尚未激活或可能正在转换。

我在这个[sql newsgroups]论坛中找到了一个主题;这表明未修补的sql server设置导致错误。

Microsoft支持链接: This will work for ~10 minutes or until microsoft changes its website document locations.

从链接:

You may receive a 913 error message when you run a query that meets the following conditions:
    -The query includes a JOIN clause that uses ANSI SQL-92 JOIN syntax. -The JOIN condition references a user-defined function. -The query includes a derived table.

文章指出您可以通过修补sql server安装来解决此问题。 (这很容易。而且,不可能,因为我们不能强制客户端更新。)或者通过简化sql语句;在我的情况下,这可能意味着减少派生表的数量。具体来说,看起来最后一个带有GROUP BY子句的问题就是问题。 (也许,一个派生表太过分了。)

那么,如何在不破坏查询的情况下简化此查询呢?

由于

    使用[mydatabase]

SELECT [Desc],
    [Series],
    [Manufacturer],
    [Distributer],
    MAX(LastOrdr) AS LastOrdr,
    [Minimum],
    SUM(Qty) AS Qty
FROM (SELECT [pptype].[Desc],
            COALESCE(cStock.Serial,' ') AS Serial,
            COALESCE([misccode].Descript,' ') AS Series,
            COALESCE((SELECT vendors.vn_Name FROM [dbo].vendors WHERE vendors.Vn_id = [pptype].Mfg),' ') AS Manufacturer,
            COALESCE((SELECT vendors.vn_Name FROM [dbo].vendors WHERE vendors.Vn_id = [pptype].Distrib),' ') AS Distributer,
            [ppType].Minimum,
            COALESCE(cQty.Qty,0) AS Qty,
            COALESCE(cStock.Recvd,0) AS LastOrdr,
            [pptype].Trkser
        FROM (SELECT [Typeid], [Serial], [Series], MAX([Recvd]) AS Recvd FROM [dbo].[ppstock] WHERE [Invoice] != 'SETUP' GROUP BY [Typeid], [Serial], [Series]) cStock
            LEFT OUTER JOIN [dbo].[pptype] ON
                cStock.[Typeid] = [pptype].Typeid
            LEFT OUTER JOIN (SELECT [Typeid], [Serial], SUM([Qty]) AS Qty FROM [dbo].[pplocatn] GROUP BY [Typeid], [Serial]) cQty ON 
                cStock.[Typeid] = cQty.[Typeid] AND cStock.Serial = CASE
                    WHEN [dbo].EMPTY(cStock.Serial) = 1 THEN 'Do not match.' ELSE cQty.[Serial] END
            LEFT OUTER JOIN [dbo].[misccode] ON
                cStock.[Series] = [misccode].[Code] AND [misccode].[type] = 'SERIES'
    WHERE [dbo].EMPTY([pptype].Inactive) = 1 and
        (COALESCE(cQty.Qty,0) < [pptype].Minimum)) cData
GROUP BY [Desc],[Series],[Manufacturer],[Distributer],[Minimum]

3 个答案:

答案 0 :(得分:1)

您可以将其中一个内部派生表分解为临时表吗? IE:

SELECT [Typeid], [Serial], [Series], MAX([Recvd]) AS Recvd
INTO #InnerTable1
FROM [dbo].[ppstock] WHERE 
[Invoice] != 'SETUP' GROUP BY [Typeid], [Serial], [Series]) cStock
                            LEFT OUTER JOIN [dbo].[pptype] ON
                                    cStock.[Typeid] = [pptype].Typeid
                            LEFT OUTER JOIN (SELECT [Typeid], [Serial], SUM([Qty]) AS Qty FROM [dbo].[pplocatn] GROUP BY [Typeid], [Serial]) cQty ON 
                                    cStock.[Typeid] = cQty.[Typeid] AND cStock.Serial = CASE
                                            WHEN [dbo].EMPTY(cStock.Serial) = 1 THEN 'Do not match.' ELSE cQty.[Serial] END
                            LEFT OUTER JOIN [dbo].[misccode] ON
                                    cStock.[Series] = [misccode].[Code] AND [misccode].[type] = 'SERIES'
            WHERE [dbo].EMPTY([pptype].Inactive) = 1 and
                    (COALESCE(cQty.Qty,0) < [pptype].Minimum


SELECT [Desc],
        [Series],
        [Manufacturer],
        [Distributer],
        MAX(LastOrdr) AS LastOrdr,
        [Minimum],
        SUM(Qty) AS Qty
FROM (SELECT [pptype].[Desc],
                        COALESCE(cStock.Serial,' ') AS Serial,
                        COALESCE([misccode].Descript,' ') AS Series,
                        COALESCE((SELECT vendors.vn_Name FROM [dbo].vendors WHERE vendors.Vn_id = [pptype].Mfg),' ') AS Manufacturer,
                        COALESCE((SELECT vendors.vn_Name FROM [dbo].vendors WHERE vendors.Vn_id = [pptype].Distrib),' ') AS Distributer,
                        [ppType].Minimum,
                        COALESCE(cQty.Qty,0) AS Qty,
                        COALESCE(cStock.Recvd,0) AS LastOrdr,
                        [pptype].Trkser
                FROM #InnerTable1) cData
GROUP BY [Desc],[Series],[Manufacturer],[Distributer],[Minimum]

这应该有效,因为内部表是你的外部查询的基础。如果涉及到连接,并且您是根据内部数据从其他表中进行选择,那么我会担心这两个查询之间发生数据更改的可能性,但是因为您从最里面的连接中选择了所有数据,使用临时表不应该有任何问题。

如果由于某种原因这不起作用,请回复,我会尝试进一步调整它,以便它。

答案 1 :(得分:1)

所以,这就是我最终要做的事情。我拆分了内部sql语句,并使用DECLARE @foo TABLE语法创建了一个临时表,我填充了INSERT INTO。然后我使用临时表进行最终选择。

此过程在我的SQL Server 2000测试环境中编译;虽然我还没有开始我的alpha测试。如果它没有结束,我会回复。

感谢。

DECLARE @cData TABLE (
    [Desc] VARCHAR(25),
    [Series] VARCHAR(40),
    [Manufacturer] VARCHAR(30),
    [Distributer] VARCHAR(30),
    [LastOrdr] CHAR(8),
    [Minimum] SMALLINT,
    [Qty] INT
)

INSERT INTO @cData (
    [Desc],
    [Series],
    [Manufacturer],
    [Distributer],
    [LastOrdr],
    [Minimum],
    [Qty]
)
    SELECT [pptype].[Desc],
            COALESCE([misccode].Descript,' ') AS Series,
            COALESCE((SELECT vendors.vn_Name FROM [dbo].vendors WHERE vendors.Vn_id = [pptype].Mfg),' ') AS Manufacturer,
            COALESCE((SELECT vendors.vn_Name FROM [dbo].vendors WHERE vendors.Vn_id = [pptype].Distrib),' ') AS Distributer,
            COALESCE(cStock.Recvd,0) AS LastOrdr,
            [ppType].Minimum,
            COALESCE(cQty.Qty,0) AS Qty
        FROM (SELECT [Typeid], [Serial], [Series], MAX([Recvd]) AS Recvd FROM [dbo].[ppstock] WHERE [Invoice] != 'SETUP' GROUP BY [Typeid], [Serial], [Series]) cStock
            LEFT OUTER JOIN [dbo].[pptype] ON
                cStock.[Typeid] = [pptype].Typeid
            LEFT OUTER JOIN (SELECT [Typeid], [Serial], SUM([Qty]) AS Qty FROM [dbo].[pplocatn] GROUP BY [Typeid], [Serial]) cQty ON 
                cStock.[Typeid] = cQty.[Typeid] AND cStock.Serial = CASE
                    WHEN [dbo].EMPTY(cStock.Serial) = 1 THEN 'Do not match.' ELSE cQty.[Serial] END
            LEFT OUTER JOIN [dbo].[misccode] ON
                cStock.[Series] = [misccode].[Code] AND [misccode].[type] = 'SERIES'
        WHERE [dbo].EMPTY([pptype].Inactive) = 1 and
            (COALESCE(cQty.Qty,0) < [pptype].Minimum)
        ORDER BY [Desc],[Series],[Manufacturer],[Distributer],[Minimum]


SELECT [Desc],
    [Series],
    [Manufacturer],
    [Distributer],
    MAX(LastOrdr) AS LastOrdr,
    [Minimum],
    SUM(Qty) AS Qty
FROM @cData
GROUP BY [Desc],[Series],[Manufacturer],[Distributer],[Minimum]
ORDER BY [Desc],[Series],[Manufacturer],[Distributer],[Minimum]

答案 2 :(得分:0)

您可能知道,但我建议在表调用上使用(NOLOCK)提示,因为您的查询涉及许多表,可能存在表锁。如果这有帮助,请告诉我。

另外我认为您可以CTE查询。试一下。