“数据库可能尚未激活或可能正在转换” 错误

发布于 2024-08-01 20:36:37 字数 2864 浏览 5 评论 0原文

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

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

它给我这个错误消息:

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

我在此找到了一个线程 [sql 新闻组] 论坛; 这表明由于未修补的 sql server 设置而导致错误。

Microsoft 支持链接:这将工作大约 10 分钟,或者直到微软更改其网站文档位置。

从链接:

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 来解决此问题服务器安装。 (这太容易了。而且,不可能,因为我们不能强制客户端更新。)或者通过简化 sql 语句; 就我而言,这可能意味着减少派生表的数量。 具体来说,看起来最后一个带有 GROUP BY 子句就是问题所在。 (也许,派生表太远了。)

那么,我该如何简化这个查询而不破坏它?

谢谢

使用[我的数据库]

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]

I have this heavily nested sql statement which works well in my sql server 2008 express.
[code block below]

However, when I move it over to our preliminary test server (sql server 2000) it doesn't work unless I use fully resolved table references in the from clauses of each statement. Which I can't do as the database name varies by installation in the field.

It gives me this error message:

Msg 913, Level 16, State 8, Line 14
Could not find database ID 102. Database may not be activated yet or may be in transition.

I've found a thread in this [sql newsgroups] forum; which suggests an error resulting from an unpatched sql server setup.

Microsoft support link: This will work for ~10 minutes or until microsoft changes its website document locations.

From the link:

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.

The article indicates that you could resolve this by patching the sql server installation. (Which would be too easy. And, impossible, since we can't force client updates.) Or by simplifying the sql statement; which in my case probably means reducing the number of derived tables. Specifically it looks like the last one with the GROUP BY clause is the problem. (Perhaps, a case of, a derived table too far.)

So, how do I go about simplifying this query without breaking it in the process?

Thanks

USE [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]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤独陪着我 2024-08-08 20:36:37

您可以将内部派生表之一分解为临时表吗? 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]

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

如果由于某种原因这不起作用,请发回,我会尝试对其进行更多调整,以使其起作用。

Can you just break one of the inner derived tables into a temp table? 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]

This should work, since the inner table is all your basing your outer query on. If there were joins involved, and you were selecting from other tables based on inner data, then I'd be concerned about the possibility of data changes that happen between these two queries, but since you're selecting all your data from the innermost join, there shouldn't be any problems using a temp table.

If this won't work for some reason, please post back and I'll try to tweak it some more so it does.

怀里藏娇 2024-08-08 20:36:37

所以,这就是我最终所做的。 我拆分了内部 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]

So, this is what I ended up doing. I split out the inner sql statement and used the DECLARE @foo TABLE syntax to create a temporary table which I filled with the INSERT INTO. I then used the temporary table for the final select.

This procedure does compile in my SQL server 2000 test environment; although I haven't yet started my alpha testing. If it doesn't end up working out I will post back.

Thanks.

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]

给妤﹃绝世温柔 2024-08-08 20:36:37

您可能知道,但我建议在表调用上使用 (NOLOCK) 提示,因为您的查询涉及许多表,因此可能会出现表锁定。 让我知道这是否有帮助。

另外我认为你可以 CTE 来回答你的问题。 试一下。

You may be aware, but I would suggest using (NOLOCK) hint on table calls, because your query involves many tables there is possible chances for a table lock. Let me know if this helps.

Also I think you can CTE for your query. Give a try.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文