SQL Insert con valore costante

di il
5 risposte

SQL Insert con valore costante

Salve a tutti

sono un po' a digiuno si SQL volevo realizzare un Insert in una tabella dove uno dei valori è sempre lo stesso mentre gli altri valori sono un elenco diverso. Ho realizzato qualcosa del genere

insert into
[dbo].[CompanySubcategoryCompany] (idCompany
,idCompanySubcategory)
values
(98582,28)
(98582,29)
....

ma volevo evitare di dover ripetere sempre 98582. C'è modo di inserire il 98582 una volta e poi di seguito tutto l'elenco di valori ?

grazie

5 Risposte

  • Re: SQL Insert con valore costante

    Versione semplice: no
    Versione complicata: si puo' fare tutto, MA dipende da quanto si vuole complicare la cosa.
    Soluzione generale: le cose semplici sono meglio
  • Re: SQL Insert con valore costante

    Concordo con te sul discorso le cose semplici sono le migliori.

    Ma se volessi complicarla come si potrebbe fare?
  • Re: SQL Insert con valore costante

    Salve,
    come dice @migliorabile, di base non esiste una funzionalita' simile... o forse non nel senso da me interpretato...
    a prescindere da cio', e' possibile definire un DEFAULT constraint a livello di singola colonna, quindi
     
    ALTER TABLE [dbo].[nomeTabella]    
        ADD CONSTRAINT [DF_nomeTabella_nomeColonna] DEFAULT ( 98582.29 ) FOR [nomeColonna];
    

    e quindi provvedere al comando di inserimento tramite
     
     INSERT [dbo].[nomeTabella]
        VALUES ( xx, yy, zz, DEFAULT );
    
    dove DEFAULT indica all'engine di utilizzare il DEFAULT constraint value definito come valore da inserire nella nuova riga...

    ma, se tu, come mi pare di aver capito, potresti VOLER cambiare nel tempo questo valore, e quindi, da quel momento sino alla prossima variazione, vuoi utilizzare quell' "ultimo valore" come nuovo default, allora la definizione di un constraint non ha molto senso... in questo caso direi abbia piu' senso utilizzare una tabella di appoggio che tu interrogherai al momento dell'insert...
    la cosa diventa un pochettino "disgustosa" ma, sempre come diceva @migliorabile, e' fattibile...
    basandoci su questa tabella di appoggio, puoi "giocare" con tali valori, ad esempio verificare che la tabella di appoggio abbia un valore predefinito per quella colonna di quella tabella, e nel caso di "assenza di valorizzazione" utilizzare tale default predefinito, ed aggiornare la tabella di appoggio in caso di valore reale definito dall'utente...
    con un esempio "triviale", bisogna innanzitutto definire "COSA" indica l'assenza di un valore utente e quindi la richiesta di del "default". definito tale "default" per la colonna, aggiungiamo tale valore alla tabella di appoggio che sara' definita, ad esempio, dal "schema + nomeTabella + nomeColonna" e il relativo valore, ospitato in un tipo sql_variant (che permette di ospitare ogni tipo di dato)...
    al momento del nuovo inserimento, verifichiamo che per la colonna il valore utente sia diverso dal "vecchio default", e nel caso aggiorniamo/aggiungiamo, e quindi utilizziamo tali valori ottenuti per il nuovo inserimento...
    per l'operazione di gestione dei default utilizziamo in questo esempio un comando di MERGE che verifica la tabella di appoggio in riferimento ai parametri che forniamo alla stored procedure di INSERT, dopo di che possiamo tranquillamente interrogare la tabella di appoggio per tutti i valori necessari, unitamente ai parametri collegati a colonne che non si appoggino su default da noi definiti...
    {spezzetto tutto il codice in blocchi perche' ho problemi a far accettare al motore delle regole del forum i comandi DDL}
    di nuovo, brutalmente, possiamo scrivere qualche cosa simile a
    
    SET NOCOUNT ON;
    USE tempdb;
    GO
    DEFINIZIONE TABELLA dbo].[tabellaX] (
    	[Id] int NOT NULL PRIMARY KEY IDENTITY,
    	[colA] int NOT NULL,
    	[ColB] decimal (18,4) NOT NULL,
    	[ColC] date  NOT NULL,
    	[ColD] varchar(10) NOT NULL,
    
    	[ColNoDefault] int
    	);
    
    DEFINIZIONE TABELLA [dbo].[DefaultValues] (
    	[TabNameColName] varchar(381) NOT NULL, -- [ + 126_char + ] + . + [ + 126_char + ] . [ + 126_char + ] + . + [ + 126_char + ]
    	[DefaultVal] SQL_VARIANT 
    	);
    GO
    -- popolamento iniziale Valori Default
    INSERT INTO [dbo].[DefaultValues]
    	VALUES	( '[dbo].[tabellaX].[colA]', 5 );
    INSERT INTO [dbo].[DefaultValues]
    	VALUES	( '[dbo].[tabellaX].[colB]', 98582.29 );
    INSERT INTO [dbo].[DefaultValues]
    	VALUES	( '[dbo].[tabellaX].[colC]', GETDATE() );
    INSERT INTO [dbo].[DefaultValues]
    	VALUES	( '[dbo].[tabellaX].[colD]', 'pippo' );
    
    SELECT *
    	FROM [dbo].[DefaultValues];
    --/ popolamento iniziale Valori Default
    
    -- popolamento iniziale Valori Default
    INSERT INTO [dbo].[DefaultValues]
    	VALUES	( '[dbo].[tabellaX].[colA]', 5 );
    INSERT INTO [dbo].[DefaultValues]
    	VALUES	( '[dbo].[tabellaX].[colB]', 98582.29 );
    INSERT INTO [dbo].[DefaultValues]
    	VALUES	( '[dbo].[tabellaX].[colC]', GETDATE() );
    INSERT INTO [dbo].[DefaultValues]
    	VALUES	( '[dbo].[tabellaX].[colD]', 'pippo' );
    
    SELECT *
    	FROM [dbo].[DefaultValues];
    --/ popolamento iniziale Valori Default
    GO
    
    segue poi un esempio di generazione di stored procedure...
    
    DDL di generazione procedura [dbo].[usp_INSERT_from_ValuesAndDefaults] (
    		@ColA int = -2147483648					--	integer.minValue come NON Value per usare il DEFAULT di appoggio
    	,	@ColB decimal(18, 4) = -2147483648		--	integer.minValue come NON Value per usare il DEFAULT di appoggio
    	,	@ColC date = '0001-01-01'				--	date.minValue come NON Value per usare il DEFAULT di appoggio
    	,	@ColD varchar(10) = '<EMPTY>'			--	<EMPTY> come NON Value per usare il DEFAULT di appoggio
    
    	,	@ColNoDefault int
    	)
    AS BEGIN
        --dichiarazione di dei default values delle singole colonne interessate,
    
    	-- CONST
    	DECLARE @defColA int = -2147483648;					--	integer.minValue come NON Value per usare il DEFAULT di appoggio
    	DECLARE @defColB decimal(18, 4) = -2147483648;		--	integer.minValue come NON Value per usare il DEFAULT di appoggio
    	DECLARE @defColC date = '0001-01-01';				--	date.minValue come NON Value per usare il DEFAULT di appoggio
    	DECLARE @defColD varchar(10) = '<EMPTY>';			--	<EMPTY> come NON Value per usare il DEFAULT di appoggio
    	-- /CONST
    
        -- utilizzo di MERGE per verificare/aggiornare la tabella di appoggio default
        riscrivo i COMANDI in italiano per evitare che il parser di validazione delle regole del forum blocchi il messaggio, dove {usando}={USING}
        
    	MERGE [dbo].[DefaultValues] AS target
    	{usando} ( SELECT '[dbo].[tabellaX].[colA]', CAST( @ColA AS SQL_VARIANT)
    			UNION SELECT '[dbo].[tabellaX].[colB]', CAST( @ColB AS SQL_VARIANT)
    			UNION SELECT '[dbo].[tabellaX].[colC]', CAST( @ColC AS SQL_VARIANT)
    			UNION SELECT '[dbo].[tabellaX].[colD]', CAST( @ColD AS SQL_VARIANT)
    			) AS source ( [TabNameColName], [DefaultVal] )
    	ON target.[TabNameColName] = source.[TabNameColName]
    	WHEN MATCHED 
    		AND (target.[DefaultVal] <> source.[DefaultVal] AND source.[DefaultVal] NOT IN ( @defColA, @defColB, @defColC, @defColD )
    		) THEN
    		UPDATE SET [DefaultVal] = source.[DefaultVal]
    	WHEN NOT MATCHED BY target THEN
    		INSERT ([TabNameColName], [DefaultVal])
    			VALUES ( source.[TabNameColName], source.[DefaultVal]);
    
    	-- recupero dei default da per tutte le colonne che lo prevedono
        WITH cte AS (
    		SELECT	CASE WHEN df.[TabNameColName] = '[dbo].[tabellaX].[colA]' AND df.[DefaultVal] IS NOT NULL THEN  df.[DefaultVal] ELSE NULL END AS '[dbo].[tabellaX].[colA]'
    			,	CASE WHEN df.[TabNameColName] = '[dbo].[tabellaX].[colB]' AND df.[DefaultVal] IS NOT NULL THEN  df.[DefaultVal] ELSE NULL END AS '[dbo].[tabellaX].[colB]'
    			,	CASE WHEN df.[TabNameColName] = '[dbo].[tabellaX].[colC]' AND df.[DefaultVal] IS NOT NULL THEN  df.[DefaultVal] ELSE NULL END AS '[dbo].[tabellaX].[colC]'
    			,	CASE WHEN df.[TabNameColName] = '[dbo].[tabellaX].[colD]' AND df.[DefaultVal] IS NOT NULL THEN  df.[DefaultVal] ELSE NULL END AS '[dbo].[tabellaX].[colD]'
    			FROM [dbo].[DefaultValues] df
    			WHERE df.[TabNameColName] IN ( '[dbo].[tabellaX].[colA]', '[dbo].[tabellaX].[colB]', '[dbo].[tabellaX].[colC]', '[dbo].[tabellaX].[colD]' )
    		),
    	cteRes AS (
    		SELECT	MAX(cte.[[dbo]].[tabellaX]].[colA]]]) AS '[dbo].[tabellaX].[colA]'
    			,	MAX(cte.[[dbo]].[tabellaX]].[colB]]]) AS '[dbo].[tabellaX].[colB]'
    			,	MAX(cte.[[dbo]].[tabellaX]].[colC]]]) AS '[dbo].[tabellaX].[colC]'
    			,	MAX(cte.[[dbo]].[tabellaX]].[colD]]]) AS '[dbo].[tabellaX].[colD]'
    			FROM cte
    		)
            -- ed infine
    		INSERT INTO [dbo].[tabellaX]
    			SELECT	CAST(c.[[dbo]].[tabellaX]].[colA]]] AS int)
    				,	CAST(c.[[dbo]].[tabellaX]].[colB]]] AS decimal(18,4))
    				,	CAST(c.[[dbo]].[tabellaX]].[colC]]] AS date)
    				,	CAST(c.[[dbo]].[tabellaX]].[colD]]] AS varchar(10))
    				,	@ColNoDefault
    				FROM cteRes c;
    END;                
    
    ed infine un test di utilizzo...
    partiamo inserendo SOLO i default,
    poi modifichiamo un parametro/default alla volta giusto per verifica...
    
    -- CONST
    DECLARE @defColA int = -2147483648;					--	integer.minValue come NON Value per usare il DEFAULT di appoggio
    DECLARE @defColB decimal(18, 4) = -2147483648;		--	integer.minValue come NON Value per usare il DEFAULT di appoggio
    DECLARE @defColC date = '0001-01-01';				--	date.minValue come NON Value per usare il DEFAULT di appoggio
    DECLARE @defColD varchar(10) = '<EMPTY>';			--	<EMPTY> come NON Value per usare il DEFAULT di appoggio
    -- /CONST
    EXEC [dbo].[usp_INSERT_from_ValuesAndDefaults] @defColA, @defColB, @defColC, @defColD, 1;
    SELECT * FROM [dbo].[tabellaX];
    
    EXEC [dbo].[usp_INSERT_from_ValuesAndDefaults] 1, @defColB, @defColC, @defColD, 2;
    SELECT * FROM [dbo].[tabellaX];
    
    EXEC [dbo].[usp_INSERT_from_ValuesAndDefaults] @defColA, 1234.56, @defColC, @defColD, 3;
    SELECT * FROM [dbo].[tabellaX];
    
    EXEC [dbo].[usp_INSERT_from_ValuesAndDefaults] @defColA, @defColB, @defColC, @defColD, 4;
    SELECT * FROM [dbo].[tabellaX];
    
    EXEC [dbo].[usp_INSERT_from_ValuesAndDefaults] @defColA, @defColB, '2019-01-01', @defColD, 5;
    SELECT * FROM [dbo].[tabellaX];
    
    EXEC [dbo].[usp_INSERT_from_ValuesAndDefaults] @defColA, @defColB, @defColC, @defColD, 6;
    SELECT * FROM [dbo].[tabellaX];
    
    EXEC [dbo].[usp_INSERT_from_ValuesAndDefaults] @defColA, @defColB, @defColC, 'pippo', 7;
    SELECT * FROM [dbo].[tabellaX];
    
    EXEC [dbo].[usp_INSERT_from_ValuesAndDefaults] @defColA, @defColB, @defColC, @defColD, 8;
    SELECT * FROM [dbo].[tabellaX];
    --<------------------------
    TabNameColName               DefaultVal
    ---------------------------- --------------------------------
    [dbo].[tabellaX].[colA]      5
    [dbo].[tabellaX].[colB]      98582.29
    [dbo].[tabellaX].[colC]      2019-09-17 14:07:33.577
    [dbo].[tabellaX].[colD]      pippo
    
    Warning: Null value is eliminated by an aggregate or other SET operation.
    Id          colA        ColB                                    ColC       ColD       ColNoDefault
    ----------- ----------- --------------------------------------- ---------- ---------- ------------
    1           5           98582.2900                              2019-09-17 pippo      1
    
    Warning: Null value is eliminated by an aggregate or other SET operation.
    Id          colA        ColB                                    ColC       ColD       ColNoDefault
    ----------- ----------- --------------------------------------- ---------- ---------- ------------
    1           5           98582.2900                              2019-09-17 pippo      1
    2           1           98582.2900                              2019-09-17 pippo      2
    
    Warning: Null value is eliminated by an aggregate or other SET operation.
    Id          colA        ColB                                    ColC       ColD       ColNoDefault
    ----------- ----------- --------------------------------------- ---------- ---------- ------------
    1           5           98582.2900                              2019-09-17 pippo      1
    2           1           98582.2900                              2019-09-17 pippo      2
    3           1           1234.5600                               2019-09-17 pippo      3
    
    Warning: Null value is eliminated by an aggregate or other SET operation.
    Id          colA        ColB                                    ColC       ColD       ColNoDefault
    ----------- ----------- --------------------------------------- ---------- ---------- ------------
    1           5           98582.2900                              2019-09-17 pippo      1
    2           1           98582.2900                              2019-09-17 pippo      2
    3           1           1234.5600                               2019-09-17 pippo      3
    4           1           1234.5600                               2019-09-17 pippo      4
    
    Warning: Null value is eliminated by an aggregate or other SET operation.
    Id          colA        ColB                                    ColC       ColD       ColNoDefault
    ----------- ----------- --------------------------------------- ---------- ---------- ------------
    1           5           98582.2900                              2019-09-17 pippo      1
    2           1           98582.2900                              2019-09-17 pippo      2
    3           1           1234.5600                               2019-09-17 pippo      3
    4           1           1234.5600                               2019-09-17 pippo      4
    5           1           1234.5600                               2019-01-01 pippo      5
    
    Warning: Null value is eliminated by an aggregate or other SET operation.
    Id          colA        ColB                                    ColC       ColD       ColNoDefault
    ----------- ----------- --------------------------------------- ---------- ---------- ------------
    1           5           98582.2900                              2019-09-17 pippo      1
    2           1           98582.2900                              2019-09-17 pippo      2
    3           1           1234.5600                               2019-09-17 pippo      3
    4           1           1234.5600                               2019-09-17 pippo      4
    5           1           1234.5600                               2019-01-01 pippo      5
    6           1           1234.5600                               2019-01-01 pippo      6
    
    Warning: Null value is eliminated by an aggregate or other SET operation.
    Id          colA        ColB                                    ColC       ColD       ColNoDefault
    ----------- ----------- --------------------------------------- ---------- ---------- ------------
    1           5           98582.2900                              2019-09-17 pippo      1
    2           1           98582.2900                              2019-09-17 pippo      2
    3           1           1234.5600                               2019-09-17 pippo      3
    4           1           1234.5600                               2019-09-17 pippo      4
    5           1           1234.5600                               2019-01-01 pippo      5
    6           1           1234.5600                               2019-01-01 pippo      6
    7           1           1234.5600                               2019-01-01 pippo      7
    
    Warning: Null value is eliminated by an aggregate or other SET operation.
    Id          colA        ColB                                    ColC       ColD       ColNoDefault
    ----------- ----------- --------------------------------------- ---------- ---------- ------------
    1           5           98582.2900                              2019-09-17 pippo      1
    2           1           98582.2900                              2019-09-17 pippo      2
    3           1           1234.5600                               2019-09-17 pippo      3
    4           1           1234.5600                               2019-09-17 pippo      4
    5           1           1234.5600                               2019-01-01 pippo      5
    6           1           1234.5600                               2019-01-01 pippo      6
    7           1           1234.5600                               2019-01-01 pippo      7
    8           1           1234.5600                               2019-01-01 pippo      8
    
    

    dove, man mano che modifichiamo i nostri default, questi verranno propagati per i successivi inserimenti...
    ricordarsi alla fine del clean up cancellando da tempdb tutti gli oggetti qui generati, PROCEDURA [dbo].[usp_INSERT_from_ValuesAndDefaults] e TABELLE [dbo].[DefaultValues], [dbo].[tabellaX];

    come vedi, non e' assolutamente "elegante", ed in questo caso e' direttamente cablata (nella rotazione di colonne su riga) sulla specificita' della tabella...
    forse pero' puo' essere di spunto per il tuo ragionamento...
    saluti omnia
    --
    Andrea
  • Re: SQL Insert con valore costante

    Grazie @Andrea

    era una mera curiosità seguirò il consiglio di @migliorabile

  • Re: SQL Insert con valore costante


    saluti omnia
    --
    Andrea
Devi accedere o registrarti per scrivere nel forum
5 risposte