Update Statement Fails - sql

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.

Related

Resolve the error: The multi-part identifier could not be bound?

I am creating a stored procedure and the final "When not matched" statement is throwing an error for the tmp.DelDate and tmp.DelUser fields. The "tmp" table is a User-Defined Table Type and the definition is below the sp code. 99 times out of 100, the problem is a bad alias or other typo. I've been staring at this and I have to be missing something small. This last statement is almost identical to the first "When Matched" statement.
ALTER Procedure dbo.spInsertUpdateProtocolRiskStrats
#riskStratsTable ProtocolRiskStrats READONLY
WITH RECOMPILE
AS
BEGIN
WITH riskStrats as (
SELECT ol.StratId,
ol.LinkType,
ol.LinkId,
ol.add_user,
ol.add_date,
ol.del_user,
ol.del_date
FROM ots_StratTriggerOutcomesLinks ol
JOIN #riskStratsTable rst on ol.LinkId = rst.LinkId
WHERE ol.LinkId = rst.LinkId
AND ol.LinkType = 2
)
MERGE riskStrats
USING #riskStratsTable as tmp
ON riskStrats.LinkId = tmp.LinkId
WHEN MATCHED THEN
UPDATE SET riskStrats.add_date = tmp.AddDate,
riskStrats.add_user = tmp.AddUser,
del_date = null,
del_user= null
WHEN NOT MATCHED THEN
INSERT (StratId, LinkType, LinkId, add_user, add_date)
VALUES (tmp.StratId, tmp.LinkType, tmp.LinkId, tmp.AddUser, tmp.AddDate)
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET riskStrats.del_date = tmp.DelDate,
riskStrats.del_user = tmp.DelUser;
END
User Table definition
CREATE TYPE dbo.ProtocolRiskStrats AS TABLE
(
KeyId int null,
StratId int null,
LinkType int null,
LinkId int null,
AddUser int null,
AddDate datetime null,
DelUser int null,
DelDate datetime null
)
As noted by #AlwaysLearning, I was assigning values that couldn't exist because it was a "not matched" condition. I updated my last statement to use constant values. I had to add another parameter to pass in user name. I could have also done a "Top 1" on my TVP but my dev lead didn't like that.
UPDATE SET riskStrats.del_date = GETDATE(),
riskStrats.del_user = #userName;

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.

Merge sql throws Unique constraint violation error

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 )

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)

How to use identity column value of target table to insert in another column of same table

Pardon the title of question if it is confusing. Table E is source and Table S is target. S.SEA_ID is identity column (int, not null). Whenever those join conditions are NOT MATCHED AND E.ACCT_NUM IS NULL, I want to insert the value 'EY|' + CAST(S.SEA_ID AS VARCHAR) in column S.ACCT_NUM. But I am getting the error
The multi-part identifier "S.SEA_ID" could not be bound.
Is it possible to insert identity column value of target table to populate another column of the same target table? If it is not possible in below MERGE statement, what are my other options?
MERGE INTO STG_EXTERNAL_ACCT S
USING ##EYDUPLICATES E
ON E.COUNTERPARTY_NAME = S.COUNTERPARTY_NAME
AND E.COUNTERPARTY_ADDRESS = S.COUNTERPARTY_ADDRESS
AND E.COUNTERPARTY_STATE = S.COUNTERPARTY_STATE
AND E.COUNTERPARTY_COUNTRY = S.COUNTERPARTY_COUNTRY
AND E.COUNTERPARTY_CITY = S.COUNTERPARTY_CITY
WHEN NOT MATCHED AND ISNULL(E.ACCT_NUM,'')=''
THEN INSERT (ACCT_NUM, COUNTERPARTY_NAME, COUNTERPARTY_ADDRESS,
COUNTERPARTY_STATE, COUNTERPARTY_COUNTRY, COUNTERPARTY_CITY)
VALUES ('EY|' + CAST(S.SEA_ID AS VARCHAR),E.COUNTERPARTY_NAME,
E.COUNTERPARTY_ADDRESS, E.COUNTERPARTY_STATE,
E.COUNTERPARTY_COUNTRY, E.COUNTERPARTY_CITY);
I suggest that change ACCT_NUM Column as calculated column.
ALTER Table STG_EXTERNAL_ACCT ALTER Column ACCT_NUM as 'EY|'+CAST(S.SEA_ID AS VARCHAR)
Also you can set this column in trigger.
Create Trigger TiggerName ON STG_EXTERNAL_ACCT
INSTEAD OF INSERT
AS Begin
Insert Into STG_EXTERNAL_ACCT (ACCT_Num, ...)
Select 'EY|'+CAST(S.SEA_ID AS VARCHAR), ...
From Inserted
End