2017-08-28 1 views
1

Je tente de sélectionner une rangée de valeurs par défaut dans une table. Cependant, je ne veux pas créer une nouvelle ligne dans ma table d'origine. Ma table d'origine a des valeurs par défaut non nulles (tous les espaces ou zéros) définies pour toutes les colonnes (à l'exception de l'identifiant unique). Je commence par la création de la table temporaire:Insertion d'une ligne de valeurs par défaut dans une table temporaire

SELECT 
    TOP 0 * 
INTO 
    #Table 
FROM 
    Database.dbo.Table 

Alors j'examine la table vide:

SELECT 
    * 
FROM 
    #Table 

Tout semble bien jusqu'à présent. Il n'y a pas de lignes, mais je peux voir toutes les colonnes de ma table d'origine. Ensuite, je tente d'insérer une seule ligne dans la table avec des valeurs par défaut pour toutes les colonnes:

INSERT INTO 
    #Table 
DEFAULT VALUES 

Plutôt que de succès, je reçois l'erreur suivante:

Cannot insert the value NULL into column 'Column', 
    table 'tempdb.dbo.#Table___0001A'; 
    column does not allow nulls. INSERT fails. 

Je prochaine essayé d'insérer rangée avec un seul champ défini.

INSERT INTO 
    #Table 
    (Column) 
VALUES 
    ('Value') 

Mêmes résultats. Il semble que les définitions des valeurs par défaut de la colonne de ma table d'origine n'ont pas été incluses dans la création de la table temporaire. Aucune suggestion?

Répondre

0

Vous devez créer votre table temporaire et y inclure les définitions par défaut.

--Check to see if table exists 
--If it does, drop it 
IF OBJECT_ID('tempdb.dbo.#Table', 'U') IS NOT NULL 
    DROP TABLE #Table 

--Create temp table with default value 
CREATE TABLE #Table 
    (
     columnA INT DEFAULT (1), 
     columnB INT DEFAULT (2), 
     columnC INT DEFAULT (3) 
    ) 

--Insert a row of default values 
INSERT INTO 
#Table 
DEFAULT VALUES 

--See it 
SELECT * 
FROM #Table 

--Drop temp table after you are done 
DROP TABLE #Table 
0

Créez votre ligne à partir du catalogue temptdb?

SELECT c.name                  AS 'Colunmn' 
,  TYPE_NAME(c.user_type_id)             AS 'Type' 
,  CASE c.is_nullable WHEN 0 THEN 'No Nulls' 
           ELSE '' END          AS 'Nullable' 
,  CASE c.default_object_id WHEN 0 THEN '' 
             ELSE 'Y' END         AS 'Has_Default' 
,  dft.definition                as Default_Value 
,  CASE ISNULL(c.max_length, -1) WHEN -1 THEN 'Variable' 
              ELSE CAST(c.max_length AS VARCHAR) END AS 'Length' 
,  ISNULL('['+OBJECT_NAME(fkc.referenced_object_id)+'].['+Cref.name+']', ' ') AS ForeignKeyInto 
FROM  tempdb.sys.tables    t 
JOIN  tempdb.sys.columns    c ON t.object_id = c.object_id 
LEFT JOIN tempdb.sys.foreign_key_columns FKC ON c.object_id = fkc.Parent_object_id 
     AND fkc.parent_column_id = c.column_id 
LEFT JOIN tempdb.sys.columns    cref ON fkc.referenced_column_id = cref.column_id 
     AND fkc.referenced_object_id = cref.object_id 
left join tempdb.sys.default_constraints dft on c.default_object_id = dft.object_id 
WHERE t.name like '#temp%' 
ORDER BY t.name 
,  c.name; 
1

Lorsque vous créez une table temporaire via SELECT ... INTO #Table la table temp obtient toutes les colonnes de la table principale, mais pas de contraintes ou d'index.

De toute évidence, vous pouvez explicitement créer une table temporaire avec toutes les contraintes nécessaires.

Une autre option consiste à insérer réellement une ligne dans la table principale, à laisser le moteur la remplir avec les valeurs par défaut, puis à lire les valeurs insérées et à les insérer dans la table temporaire. Tout cela dans une transaction. Puis annulez la transaction, de sorte que la table principale reste telle qu'elle était. Pour que cela fonctionne, vous devez utiliser la variable table au lieu de la table temporaire, car les tables temporaires participent aux transactions en tant que tables normales, mais pas les variables de table. Cela signifie que vous devez définir la variable de table à l'avance, vous devez donc connaître les colonnes de votre table d'origine. Mais, au moins, vous n'avez pas besoin de connaître la définition des contraintes par défaut. En outre, si votre table principale a une colonne INDENTITY, cette insertion-annulation crée un espace dans les valeurs d'identité.

Table d'échantillons

CREATE TABLE [dbo].[MainTable](
    [Col1] [int] NOT NULL, 
    [Col2] [nvarchar](50) NOT NULL, 
    [Col3] [date] NOT NULL 
) ON [PRIMARY] 
GO 

ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col1] 
DEFAULT ((123)) FOR [Col1] 
GO 

ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col2] 
DEFAULT ('qwerty') FOR [Col2] 
GO 

ALTER TABLE [dbo].[MainTable] ADD CONSTRAINT [DF_MainTable_Col3] 
DEFAULT (getdate()) FOR [Col3] 
GO 

Query

DECLARE @T TABLE (Col1 int, Col2 nvarchar(50), Col3 date); 

BEGIN TRANSACTION; 

INSERT INTO dbo.MainTable 
OUTPUT inserted.Col1, inserted.Col2, inserted.Col3 
INTO @T (Col1, Col2, Col3) 
DEFAULT VALUES; 

ROLLBACK TRANSACTION; 

SELECT * 
FROM @T; 

Résultat

+------+--------+------------+ 
| Col1 | Col2 | Col3 | 
+------+--------+------------+ 
| 123 | qwerty | 2017-08-29 | 
+------+--------+------------+