How do I fix my trigger query so that the multi-part identifiers can be bound? - sql

I'm working on a trigger which will allow me to store all the previous data inside specified columns on my Customer table into a specified audit-table once those columns are updated. The fields I'm taking from the customer table and storing are specific, as there are multiple fields on the customers table and I am only trying to store the (CustomerID, CustomerAddress and CustomerPostcode)
Here is the fields in the Customer table:
[CustomerID]
[CustomerName]
[CustomerAddress]
[CustomerPostcode]
[CustomerTelephone]
[CardNumber]
[CountyID]
I am only trying to take [CustomerID], [CustomerAddress] and [CustomerPostcode]
In order to store these specific fields I set up an audit table to the best of my ability which will store those fields, but also display auto-generated fields based on the trigger.
Here is the Audit-Table I set up:
CREATE TABLE Customer_Audit
(
Cust_UpdateID int IDENTITY (1,1),
Cust_User char (8),
Cust_Update_Date date,
CustomerID int,
CustomerAddresss nvarchar (255),
CustomerPostCode nvarchar (255),
CONSTRAINT [pk_Cust_UpdateID] PRIMARY KEY (Cust_UpdateID)
)
Here is the trigger query I've set up:
CREATE TRIGGER Customer_Update_Trigger ON tblCustomer
AFTER UPDATE
AS
BEGIN
INSERT INTO Customer_Audit (Cust_User, Cust_Update_Date, Cust_ID, CustomerAddresss, CustomerPostCode)
SELECT
CURRENT_USER,
GETDATE(),
d.CustomerID,
d.CustomerAddress,
d.CustomerPostcode
FROM deleted
END
In order to store the data I'm trying to take the fields from the deleted table but every time I do it I keep getting the following error messages:
Msg 4104, Level 16, State 1, Procedure Customer_Update_Trigger, Line 11
The multi-part identifier "d.CustomerID" could not be bound.
Msg 4104, Level 16, State 1, Procedure Customer_Update_Trigger, Line 12
The multi-part identifier "d.CustomerAddress" could not be bound.
Msg 4104, Level 16, State 1, Procedure Customer_Update_Trigger, Line 13
The multi-part identifier "d.CustomerPostcode" could not be bound
I don't know what it is I'm doing wrong, I know the field names in the deleted table match the field names in the customer table, but it still refused to process.

you are missing an alias for deleted, try adding FROM deleted as d
CREATE TRIGGER Customer_Update_Trigger ON tblCustomer
AFTER UPDATE AS
BEGIN;
INSERT INTO Customer_Audit (
Cust_User
, Cust_Update_Date
, Cust_ID
, CustomerAddresss
, CustomerPostCode
)
SELECT
CURRENT_USER
, GETDATE()
, d.CustomerID
, d.CustomerAddress
, d.CustomerPostcode
FROM deleted as d;
END;

Related

How to fix this message error that i cant create table using script?

I just want to make a new table in database, when I create table just got some messages like
Msg 102, Level 15, State 1, Line 5 Incorrect syntax near 'tbl_invoice'".
So my question is where do I start to make a new table?
use master
use db_penjualan
create table tbl_invoice (
no_invoice varchar primary key (10),
jenis_pembayaran varchar(25),
user_generate varchar (10),
tgl_terbit date not null )
;
Messages
Msg 102, Level 15, State 1, Line 5 Incorrect syntax near
'tbl_invoice'.
The problem lies with primary key declaration syntax. Write it as:
use db_penjualan
Go
create table tbl_invoice (
no_invoice varchar(10),
jenis_pembayaran varchar(25),
user_generate varchar (10),
tgl_terbit date not null ,
primary key(no_invoice)--define primary key col here
)
;

Inserting into Output table in an insert with from clausule [duplicate]

This question already has answers here:
Using OUTPUT clause to insert value not in INSERTED
(2 answers)
Closed 4 years ago.
I'm trying to duplicate some rows in a table, with a couple of changed values, and I also need to store an old (that will be lost) id to do further processing later. I'm trying to use the Output Clausule to store that information, but SQL Server is throwing the following error:
Msg 4104 <...> The multi-part identifier could not be bound.
This is the table I'm duplicating the data (slightly modified to reduce the number of columns):
Create Table Elements
(
id int Identity(0,1) not null, --PK
name varchar(50) not null,
modelID int not null, --FK
constraint PK_Elements primary key (id)
);
And this is my my query:
declare #outputTable table
(
oldElementID int,
id int,
name varchar(50),
modelID bigint
);
Insert into Elements
(name, modelID)
Output e.id as oldElementID,
Inserted.id,
Inserted.name,
Inserted.modelID into #outputTable
select e.name, #newModelID
from Elements as e
where e.modelID = #oldModelID
Note: #oldModelID and #newModelID are previously declared and set.
I'm not sure if my logic is wrong and I have to take a different approach (but I was sure it was possible to do it this way). Or if I simply have an error that I can't quite put my finger on it.
Any help would be appreciated.
Thanks!
I recreated the problem like this:
CREATE TABLE #a (a INT, b INT)
INSERT INTO #a (a,b) VALUES (42, 43)
INSERT INTO #a (a, b)
OUTPUT a.a, a.b, inserted.a, inserted.b
SELECT a.b, a.a
FROM #a a
The insert operation produces the messages:
Msg 4104, Level 16, State 1, Line 7
The multi-part identifier "a.a" could not be bound.
Msg 4104, Level 16, State 1, Line 7
The multi-part identifier "a.b" could not be bound.
that's because the INSERT command cannot see the alias 'a' that I used in the select command.

Solve primary key violation in SSMS

While trying to insert some items into a table I get the following error:
Msg 2627, Level 14, State 1, Procedure dba_create_fake_orders, Line 95 [Batch Start Line 2]
Violation of PRIMARY KEY constraint 'PK_OrderItem_1'. Cannot insert duplicate key in object 'dbo.OrderItem'. The duplicate key value is (10000, 100009).
Here's how my tables are set up and the following code is just a segment of the code used to insert those items to the table:
Table Set UP
INSERT INTO Orders(order_id, customer_id, sub_total, tax_total,
grand_total, date_created)
SELECT
#order_id, #customer_id, 0, 0,
0, #date_created
INSERT INTO OrderItem (order_id, quantity, game_id, price_id)
SELECT
#order_id, #quantity, game_id, price_id
FROM
GameVersion
WHERE
game_id = #game_id
#order and #customer_id are taken from a flat customer table and are chosen at random. The OrderItem table is empty always so I'm not sure why it's saying that there's a duplication error. The only tables that are populate is Orders and GameVersion.
GameVersion is populated way before and Orders is done just before OrderItem. I'm assuming the issue is that since I have to keys then it might be complaining since they might be the same number but I'm still not sure.
If the following query returns more than one row then it means your dataset has duplicate value in the column set you are using as PK in OrderItem.
select count(*), game_id from GameVersion GROUP BY game_id having count(*)>1

Can't find columns after declaration in SQL Server

I have a problem. I am creating a trigger which will prompt the user to not create a purchase order with a higher cost to their selling cost. I have declared a column on my script but its still showing this error:
Msg 207, Level 16, State 1, Procedure _trgZSCheckPrice, Line 31 [Batch Start Line 7]
Invalid column name 'fExclPrice'
The two columns are #Check and #Excl
I have attached my code below any help is advisable:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER _trgZSCheckPrice
ON [dbo].[_btblInvoiceLines]
FOR INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE
#Valid int,
#ValidPO int,
#DocType int,
#DocState int,
#Check int,
#Excl float,
#POPrice float
SELECT
#Check = ubIICheck,
#Excl = fExclPrice,
#POPrice = fUnitPriceExcl
FROM
INSERTED
SELECT
#Excl = fExclPrice,
#Check = ubIICheck
FROM
stkitem A
INNER JOIN
_etblPriceListPrices B ON A.StockLink = B.iStockID
SELECT
#POPrice = fUnitPriceExcl
FROM
_btblInvoiceLines C
LEFT JOIN
InvNum D ON C.iInvoiceID = D.AutoIndex
BEGIN
IF (#DocType = 5 AND #DocState <> 7) AND #CHECK = 1
BEGIN
IF #Excl > #POPrice
BEGIN
RAISERROR ('Message from Management:
You are not allowed to Purchase above Selling Cost.
The transaction will be rolled back. ', 16, 1)
ROLLBACK TRANSACTION
END
END
END
END
It seems like ideally, here, you'd be implementing this as a multi-table CHECK constraint (in fact, in standard SQL, these are called ASSERTIONs. So far as I'm aware, only Postgre implements them).
If you're happy to trade away the ability to completely control the error message, I'd usually prefer to implement this in a declarative manner rather than relying on a trigger.
Here's how to do such a check with an indexed view. First a couple of tables that are somewhat like your problem domain (but not very fleshed out since you didn't put any definitions in your question):
create table dbo.ListPrices (
ID int not null,
Price decimal(12,4) not null,
constraint PK_ListPrices PRIMARY KEY (ID)
)
create table dbo.Orders (
ID int not null,
ListPriceID int not null,
MyPrice decimal(12,4) not null,
constraint PK_Orders PRIMARY KEY (ID),
constraint FK_Orders_ListPrices FOREIGN KEY (ListPriceID)
references dbo.ListPrices (ID)
)
go
insert into dbo.ListPrices (ID,Price) values (1,12.50),(2,25.00)
And now we create a special helper table. It's not needed if you already have a suitable table (such as a numbers table) in your database:
create table dbo.Two (
n int not null,
constraint PK_Two PRIMARY KEY (n),
constraint CK_Two_Only CHECK (n in (1,2))
)
go
insert into dbo.Two (n) values (1),(2)
And now we create the view:
go
create view dbo.DRI_NoOrderPricesOverListPrices
with schemabinding
as
select
1 as p /* Constant */
from
dbo.Two t
cross join
dbo.Orders o
inner join
dbo.ListPrices lp
on
o.ListPriceID = lp.ID
where
/*Conditions for failure*/
o.MyPrice > lp.Price
go
create unique clustered index IX_NoOrderPricesOverListPrices
on DRI_NoOrderPricesOverListPrices(p)
The key feature here is that the view joins all of the tables we're interested in together and we can put whatever conditions we like in the where clause, referencing multiple tables, comparing column values, etc.
The conditions we're specifying is for what shouldn't be allowed in the database. So, we're saying we should be able to insert a row in Orders provided that its price is less than or equal to the price in line items.
And we can. This insert succeeds:
insert into Orders (ID,ListPriceID,MyPrice) values (1,2,17.00)
And this one fails:
insert into Orders (ID,ListPriceID,MyPrice) values (2,1,17.00)
Msg 2601, Level 14, State 1, Line 42
Cannot insert duplicate key row in object 'dbo.DRI_NoOrderPricesOverListPrices' with unique index 'IX_NoOrderPricesOverListPrices'. The duplicate key value is (1).
(As I said at the top, we don't get so much control over the error message - but making a good choice of name here should make it reasonable to deduce what's happening and directly exposing SQL Server error messages to the users is something I'd generally try to avoid)

Error while dropping a column

I just created a table as below in MS SQL
create table Employee
(emp_id smallint not null,
employee_name varchar (30) not null,
salary money not null,
department varchar(30),
address varchar(40),
primary key(emp_id)
)
After creating the table, I feel like auto populating the emp_id column( using Identity). So, I was trying to drop the column emp_id as below:
alter table Employee
drop column emp_id
Even though, I haven't inserted any rows in the table yet, I am getting the error
Msg 5074, Level 16, State 1, Line 1 The object
'PK__Employee__1299A86183CA4FBC' is dependent on column 'emp_id'. Msg
4922, Level 16, State 9, Line 1 ALTER TABLE DROP COLUMN emp_id failed
because one or more objects access this column.
Please help!!!
Something like this can help .
ALTER TABLE Employee
DROP CONSTRAINT PK__Employee__1299A86183CA4FBC;
alter table Employee
drop column emp_id
I solved the problem by executing below query: I need to remove a column and all the entries from that column to free my DB size my initial table structure is as shown below:
CREATE TABLE words(_id,word,synonyms,favorite,history,updDate)
And I wanted the table in below form
CREATE TABLE words(_id,word,favorite,history,updDate)
So I executed below query and it removed "synonyms" column
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(_id,word,favorite,history,updDate);
INSERT INTO t1_backup SELECT _id,word,favorite,history,updDate FROM words;
DROP TABLE words;
CREATE TABLE words(_id,word,favorite,history,updDate);
INSERT INTO words SELECT _id,word,favorite,history,updDate FROM t1_backup;
DROP TABLE t1_backup
COMMIT;