2009-08-12 7 views
3

J'ai cette instruction sql fortement imbriquée qui fonctionne bien dans mon serveur sql 2008 express.
[bloc de code ci-dessous]'La base de données ne peut pas encore être activée ou peut être en cours de transition' erreur

Cependant, quand je le déplacer vers notre serveur de test préliminaire (SQL Server 2000), il ne fonctionne pas à moins d'utiliser des références de table entièrement résolues dans les des clauses de chaque déclaration. Ce que je ne peux pas faire car le nom de la base de données varie en fonction de l'installation sur le terrain.

Il me donne ce message d'erreur:

Msg 913, niveau 16, état 8, ligne 14 Impossible base de données Clé 102. Base de données ne peut pas être encore activé ou peut-être en transition.

J'ai trouvé un fil de discussion dans ce forum [sql newsgroups]; ce qui suggère une erreur résultant d'une installation de serveur sql non corrigée.

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

À partir du lien:

 
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.

L'article indique que vous pouvez résoudre ce problème en patcher l'installation du serveur SQL. (Ce qui serait trop facile Et, impossible, puisque nous ne peut pas forcer les mises à jour client.) Ou en simplifiant l'instruction SQL; ce qui dans mon cas signifie probablement réduire le nombre de tables dérivées. Plus précisément, il semble que le dernier avec la clause GROUP BY est le problème. (Peut-être, un cas de, une table dérivée trop loin.)

Alors, comment puis-je simplifier cette requête sans la casser dans le processus?

Merci

UTILISATION [mabase]

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] 

Répondre

1

Donc, c'est ce que j'ai fini par faire. Je diviser l'instruction sql interne et utilisé la syntaxe DECLARE @foo TABLE pour créer une table temporaire que j'ai rempli avec le INSERT INTO. J'ai ensuite utilisé la table temporaire pour la sélection finale.

Cette procédure est compilée dans mon environnement de test SQL Server 2000; Bien que je n'ai pas encore commencé mes tests alpha. Si ça ne finit pas, je posterai.

Merci.

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] 

0

Vous savez peut-être, mais je suggère d'utiliser (NOLOCK) indication sur les appels de table, parce que votre requête implique de nombreuses tables il y a des chances possibles pour un verrou de table. Faites-moi savoir si cela aide.

Aussi je pense que vous pouvez CTE pour votre requête. Essayer. Pouvez-vous simplement casser une des tables dérivées internes dans une table temporaire?

+0

nolock, bien sûr, rend également les résultats moins précis - donc si le résultat peut être une approximation, c'est OK. – onupdatecascade

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] 

Cela devrait fonctionner, car la table interne est tout votre bas sur votre requête externe. S'il y avait des jointures impliquées, et que vous sélectionniez à partir d'autres tables basées sur des données internes, je serais inquiet de la possibilité de changements de données entre ces deux requêtes, mais puisque vous sélectionnez toutes vos données depuis la jointure la plus interne , il ne devrait pas y avoir de problèmes en utilisant une table temporaire.

Si cela ne fonctionne pas pour une raison ou une autre, veuillez le poster et j'essaierai de le peaufiner davantage.

+0

C'est en fait ce sur quoi je travaille en ce moment. Si cela fonctionne, je vais poster le code. – Cynthia

Questions connexes