Merge sql throws Unique constraint violation error - sql

I have below two table for which when i query table TEST_RUA:
select CLASS, ID_LL, ID_UU, TKR from TEST_RUA where ID_UU= 'GV9999B12M0'
it returns:
CLASS ID_LL ID_UU TKR
Bond (null) GV9999B12M0 WIB
When i query table TEST_RUA_MER:
select CLASS, ID_LL, ID_UU, TKR from TEST_RUA_MER where ID_UU= 'GV9999B12M0'
it returns:
CLASS ID_LL ID_UU TKR
Bond (null) GV9999B12M0 WIB
You can see both the values are same for table where ID_UU= 'GV9999B12M0'. The table TEST_RUA_MER has unique index on columns ID_LL, ID_UU, TKR.
Now i have below merge query which throws error as ORA-00001: unique constraint violated and i dont understand how can i avoid this error as both the table values are same then in this case this merge query should try to update and not to insert in table TEST_RUA_MER .
merge into TEST_RUA_MER h using (
select distinct r.CLASS, r.ID_LL, r.ID_UU, r.TKR from TEST_RUA r ) s
on (s.ID_LL=h.ID_LL and s.ID_UU=h.ID_UU and s.TKR=h.TKR) when matched then
update set h.CLASS = s.CLASS, h.ID_LL = s.ID_LL, h.ID_UU = s.ID_UU, h.TKR = s.TKR
when not matched then insert values (s.CLASS, s.ID_LL, s.ID_UU, s.TKR);

Looks like NULL causes problems; it isn't "equal" to anything, so this:
on (s.ID_LL=h.ID_LL
fails.
Try with
on (nvl(s.ID_LL, -1) = nvl(h.ID_LL, -1)
(depending on what ID_LL column's datatype is; I presumed it is a number).

Yes, As mentioned in the other answer also, cause of the error is s.ID_LL=h.ID_LL. You can update it as
( s.ID_LL=h.ID_LL OR (s.ID_LL is null and h.ID_LL is null) )
OR
( s.ID_LL=h.ID_LL OR coalesce(s.ID_LL, h.ID_LL) is null )

Related

INSERT row in table a for every row in table b [duplicate]

If I have an SQL table with all default columns (e.g. identity column + any number of columns all with default values), what is the SQL statement to insert a row with no explicit values given?
insert MyTable /* ( doh, no fields! ) */
-- values( doh, no values! )
What's the trick?
This is a part of the INSERT syntax
INSERT INTO TableName DEFAULT VALUES
Read more here:
https://learn.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql
You can use the DEFAULT keyword.
The accepted answer only works for one row, not for multiple rows.
Let us assume you know how many rows to insert, but you want all default values. You cannot do the following, for instance
INSERT MyTable
SELECT DEFAULT VALUES -- Incorrect syntax near the keyword 'DEFAULT'.
FROM SomeQueryOrView;
-- or
INSERT MyTable
DEFAULT VALUES -- Incorrect syntax near the keyword 'FROM'.
FROM SomeQueryOrView;
Instead we can hack MERGE to do this
MERGE INTO myTable
USING (SELECT SomeValue FROM SomeQueryOrView) s
ON 1 = 0 -- never match
WHEN NOT MATCHED THEN
INSERT DEFAULT VALUES;
A bonus benefit is that we can OUTPUT data from columns which are not being inserted:
MERGE INTO myTable
USING (SELECT SomeValue FROM SomeQueryOrView) s
ON 1 = 0 -- never match
WHEN NOT MATCHED THEN
INSERT DEFAULT VALUES
OUTPUT inserted.Id, s.SomeValue;

SQL to catch incremental entries from a view

I have a historic table that won't be updated with new inserts, and a have a view that everyday will be update with new inserts. So I need to know if my SQL is correct.
This SQL needs to get all entries that inside in FATO_Proposta_Planilha table (Table 1)
and to add the entries not similar that are in the FATO_Proposta_View table (Table 2).
So, this SQL must have all entries from Table 1 more all entries from Table 2 that are not repeated in the Table 1. Can you give a opinion about this SQL, please?
SELECT vw.[DescPac] [PA]
,vw.[DescRegional] [Regional]
,vw.[DescSuperintendencia] [Superintendencia]
,vw.[NUM_CPF_CNPJ] [Documento_Numero]
,pla.[Nome] [Nome]
,pla.[Produto] [Produto]
,pla.[Modalidade] [Modalidade]
,vw.[NUM_CONTRATO_CREDITO] [Contrato]
,vw.[DESC_FINALIDADE_OPCRED] [Finalidade]
,vw.[DATA_OPERACAO] [Data_operacao]
,pla.[Data_mov_entrada] [Data_mov_entrada]
,vw.[DATA_VENC_OPCRED] [Data_vencimento]
,vw.[VALOR_CONTRATO_OPCRED] [Valor_contrato]
,pla.[Processo_Lecon] [Processo_Lecon]
,CASE WHEN ISNULL(pla.Origem, '') = ''
THEN 'Esteira Convencional'
ELSE pla.Origem
END [Origem]
FROM Proposta_View vw
LEFT JOIN FATO_Proposta_Planilha pla
ON vw.NUM_CONTRATO_CREDITO = pla.Contrato
UNION
SELECT [PA] [PA]
,[Regional] [Regional]
,[Superintendencia] [Superintendencia]
,[Documento_Numero] [Documento_Numero]
,[Nome] [Nome]
,[Produto] [Produto]
,[Modalidade] [Modalidade]
,[Contrato] [Contrato]
,[Finalidade] [Finalidade]
,[Data_operacao] [Data_operacao]
,[Data_mov_entrada] [Data_mov_entrada]
,[Data_vencimento] [Data_vencimento]
,[Valor_contrato] [Valor_contrato]
,[Processo_Lecon] [Processo_Lecon]
,CASE WHEN ISNULL(Origem, '') = ''
THEN 'Esteira Convencional'
ELSE Origem
END [Origem]
If you are only inserting rows through the view you can add an extra column with a DEFAULT value to distinguish the old rows from the new ones.
For example if you have a table t as:
create table t (a int primary key not null);
insert into t (a) values (123), (456);
You can add the extra column as:
alter table t add is_new int default 1;
update t set is_new = 0;
create view v as select a from t;
Then each insert through the view won't see that new column and will insert with value 1.
insert into v (a) values (789), (444);
Then it's easy to find the new rows:
select * from t where is_new = 1;
Result:
a is_new
---- ------
444 1
789 1
Se running example at db<>fiddle.

sqlite3 NOT NULL constraint failed despite specific not null value

despite none NULL value in column preptime2 (value = 7), SQLite is throwing exception:
NOT NULL constraint failed.
The excerpt below is showing
(1) value in menucard_meal.preptime2 (value = 7)
and then
(2) the try to INSERT INTO same data in table orders_meal which throws the error.
sqlite> select preptime2 from menucard_meal where id = 32;
7
sqlite> INSERT INTO orders_meal SELECT * from menucard_meal where id = 32;
Error: NOT NULL constraint failed: orders_meal.preptime2
sqlite>
Has someone any idea what happens here? Thnx
In this statement:
INSERT INTO orders_meal
SELECT * from menucard_meal
where id = 32;
there are 2 tables involved: orders_meal and menucard_meal.
In the above statement you do not list the columns of either table.
This is not required but it is a good practice and usually it saves you from problems like (I suspect) this one.
List the columns for both tables and make sure that the corresponding columns are in the same order, like:
INSERT INTO orders_meal(column1, column2, columnforpreptime2, ...)
SELECT col1, col2, preptime2, ...
from menucard_meal
where id = 32;

Database inner join update

I am trying to update a table column from a table column in another table and am using the following code - it generates the error below.
Any ideas?
UPDATE URLRecord
  SET URLRecord.Slug = aaNewURLSlugss.NewSlugName
FROM URLRecord
INNER JOIN aaNewURLSlugs ON URLRecord.Slug = aaNewURLSlugss.OldSlugName
Error:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
SQL Server doesn't like the qualified column name in SET. Does this work?
UPDATE r
SET Slug = n.NewSlugName
FROM URLRecord r inner join
aaNewURLSlugs n
ON r.Slug = n.OldSlugName;
The error message would be different, though, from what you are getting. This would be an additional error.
Here is a working solution that uses a temporary table. It may not be ideal and I've included some drop statements, so don't run this on your production machine.
-- Build our test tables
CREATE TABLE [URLRecord]
(
[Id] INTEGER IDENTITY PRIMARY KEY,
[Slug] CHARACTER VARYING(255) NOT NULL
)
GO
CREATE TABLE [NewSlugs]
(
[Id] INTEGER IDENTITY PRIMARY KEY,
[NewSlugName] CHARACTER VARYING(255) NULL,
[OldSlugName] CHARACTER VARYING(255) NULL
)
GO
-- Insert test data
INSERT INTO [URLRecord] VALUES ('Original Name');
INSERT INTO [NewSlugs] VALUES ('New Name', 'Original Name');
-- Populate work table with the records we want to modify
SELECT [URLRecord].[Id], [NewSlugs].[NewSlugName] INTO #SlugWork
FROM [URLRecord]
INNER JOIN [NewSlugs] ON [URLRecord].[Slug] = [NewSlugs].[OldSlugName]
-- We're just echoing here
SELECT * FROM #SlugWork
-- Pull everything from our temporary table and update modified records
UPDATE [URLRecord]
SET [URLRecord].[Slug] = [T].[NewSlugName]
FROM #SlugWork AS [T]
WHERE [T].[Id] = [URLRecord].[Id]
-- Proving it's updated
SELECT * FROM [URLRecord]
-- Drop our example stuff, for rerunnability
DROP TABLE #SlugWork
DROP TABLE [NewSlugs]
DROP TABLE [URLRecord]
Try using Aliases
UPDATE A
SET A.Slug = B.NewSlugName
FROM URLRecord AS A
INNER JOIN aaNewURLSlugs B
ON A.Slug = B.OldSlugName
Try to use embedded sql like this:
UPDATE URLRecord
SET Slug = (
SELECT NewSlugName
FROM aaNewURLSlugs
WHERE URLRecord.Slug = aaNewURLSlugs.OldSlugName )
WHERE Slug IN (SELECT OldSlugName FROM aaNewURLSlugs)

Update Statement Fails

I have a table called [dbo].[ProductComponentRelationship] with 4 fields
[ProductComponentRelationshipID] PK, INt, Not Null
[ProductItemID] FK, Int Not Null
[ComponentItemID] FK, Int, Not Null
[SequenceNumber] int null
This table houses a bunch of values. I need to update 4000 records in the table above. Therefore i populated a seperate table with a productItemID, and the new ComponentitemID value. I tried to run the sql statement below and it failed:
update ProductComponentRelationship set ComponentItemID =
(select compid from cst_pricefix where
ProductComponentRelationship.ProductItemID = cst_pricefix.prditem and
ProductComponentRelationship.ProductComponentRelationshipID = ProductComponentRelationship.ProductComponentRelationshipID )
Error Message:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'ComponentItemID', table 'SDSDB.dbo.ProductComponentRelationship'; column does not allow nulls. UPDATE fails.
If this is SQL Server, which it looks like from the dbo, you can update over a join like so:
update
pcr
set
ComponentItemID = f.compid
from
ProductCompnentRelationship pcr
inner join
cst_pricefix f
on pcr.ProductItemID = f.prditem
I'm not sure what ProductComponentRelationship.ProductComponentRelationshipID = ProductComponentRelationship.ProductComponentRelationshipID was about in your original query, so there may be something missing from mine.