I wanna update remote table with following code but I encounter this error:
`Msg 208, Level 16, State 1, Line 12
Invalid object name 'f1'.`
code:
declare #temp table
(
co_kargah bigint,
code_ostan nvarchar(10)
)
insert into #temp
select co_kargah,code_ostan
from Tbl_ghireHadese_Temp
where InsUpKey=2
update f1 /* Error location*/
set
f1.modate_mogharar=tbl_ghireHadese.modate_mogharar,
f1.t_pm_mogharar=tbl_ghireHadese.t_pm_mogharar
from openquery([lnkworkersystem],'select * from Bazresi_Kar.dbo.Tbl_ghireHadese') f1
inner join #temp temp
on temp.co_kargah=f1.co_kargah
and temp.code_ostan=f1.code_ostan
and temp.t_bazresiFE=f1.t_bazresiFE
inner join tbl_ghireHadese
on temp.co_kargah=tbl_ghireHadese.co_kargah
and temp.code_ostan=tbl_ghireHadese.code_ostan
and temp.t_bazresiFE=tbl_ghireHadese.t_bazresiFE
The error is in the SET clause. You can't specify aliases in the column assign. There is no need because you've already told SQL Server what table in the UPDATE clause
Should be:
update f1
set
modate_mogharar = tbl_ghireHadese.modate_mogharar,
t_pm_mogharar = tbl_ghireHadese.t_pm_mogharar
from
....
Note: SQL Server doesn't always give the correct line number for errors
Edit: use 4 part object names as normal tables
...
FROM
lnkworkersystem.Bazresi_Kar.dbo.Tbl_ghireHadese
inner join
#temp temp on temp.co_kargah=f1.co_kargah
...
Also, your temp table has 3 columns in the JOIN but is only defined with 2. t_bazresiFE is missing. So it will error again...
Related
As part of the company I am working for at the moment I need to create some database upgrade scripts to replace some work of a previous contractor.
The code before the following block runs, creates the new ID column, and then this script looks to populate the values and then drop some columns.
IF EXISTS (
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID(N'[Central].[Core.Report].[ReportLessonComp]')
AND name = 'Name')
and
EXISTS (
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID(N'[Central].[Core.Report].[ReportLessonComp]')
AND name = 'Code')
BEGIN
UPDATE
[Central].[Core.Report].[ReportLessonComp]
SET
CompetencyId = rc.Id
FROM
[Central].[Core.Report].[ReportLessonComp] rlc
INNER JOIN
[Core.Lookup].ReportCompetency rc
ON
rc.Code = rlc.Code and rc.Name = rlc.Name
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN CODE
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN [Name]
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN [Description]
END
GO
When running the if exists \ not exists checks and then select getdate() this works perfeclty fine and gives me the result I expect.
However, when I run the code block above I get error
Msg 207, Level 16, State 1, Line 23
Invalid column name 'Code'.
Msg 207, Level 16, State 1, Line 23
Invalid column name 'Name'.
This script it part of a larger upgrade script and is used in a system calle RoundHouse https://github.com/chucknorris/roundhouse which is the system chosen by the company.
Prior to the above if exists check,
IF (SELECT COUNT(1) FROM sys.columns
WHERE OBJECT_ID = OBJECT_ID('[Central].[Core.Report].[ReportLessonComp]')
AND Name in ('Name','Code')) = 2
which also gave the same issue. I have five tables that I need to update and this is going to stop the team from working if I cant resolve this at my next PR
What can I do in order to stop this from causing the upgrade scripts to fail?
EDIT -- The reason I am linking on varchar fields also is because the previous developer did not create relationships between tables, and was just inserting strings into tables rather than relating by ID causing the potential for unlinked \ inconsistent data.
The table edit prior to this creates the new id column, and this script is getting the value and dropping columns that are no longer needed
SQL Server will parse the whole of the statement prior to execution, so the exists check does not protect you from the update being parsed. If the column has already been dropped, that makes the statement invalid and you get a parse error. The update statement would have to be executed as dynamic SQL, sp_execute basically so that the varchar of the update is not directly parsed.
For SQL Server 2016 and above the drop column can be protected a bit more as well:
ALTER TABLE [Central].[Core.Report].[ReportLessonComp] DROP COLUMN IF EXISTS CODE
We have three tables:
1.CourseRequest with fields Request_id, ExecutionStartingDate, ExecutionEndDate.
2.Courselist with fields list_id ,Request_id ,Planning_id
3.CoursePlanning with fields Planning_Id and CourseLength.
Image of table structure:
I want for each time data inserted the ExecutionEndDate will be computed from ExecutionStartingDate + length and consider that the datatypes are datatime2 and int respectively with trigger.
Basically you need to do the below:
Create a trigger for insert
Compute and update the executionEndDate field as required - for the update, you will need to join all 3 tables to find the related mapping.
Something like the below query:
CREATE TRIGGER TRG_CourseRequest ON dbo.CourseRequest --Create insert trigger for table
FOR INSERT AS
BEGIN
--Get the newly inserted CourseRequest ID
DECLARE #COURSE_REQ_ID INT
SET #COURSE_REQ_ID = (SELECT Request_id FROM INSERTED)T
UPDATE CR --Update the details
SET CR = DATEADD(CR.EXECUTIONSTARTINGDATE,CP.LENGTH)
FROM CourseRequest CR
INNER JOIN COURSELIST CL
ON CR.REQUEST_ID = CL.REQUEST_ID
INNER JOIN COURSEPLANNING CP
ON CP.PLANNING_ID = CL.PLANNING_ID
WHERE
CR.REQUEST_ID = #COURSE_REQ_ID
END
I haven't compiled this in SQL server so there might be some syntax errors!
I'm trying to insert a row into a new table when a row is deleted from the original table but I keep getting the below error when i run a delete on a record.
I read error message details and it says it has something to do with type of data cannot be inserted but I don't understand this since I copied exact table structure that it was deleted from to be inserted to.
Msg 8152, Level 16, State 13, Procedure DeleteEmpTR, Line 5
String or binary data would be truncated.
The statement has been terminated.
SELECT * INTO dbo.DeletedEmp
FROM Original.Employees
WHERE 1=2;
CREATE TRIGGER dbo.DeleteEmpTR ON dbo.Employees
AFTER DELETE
AS
INSERT INTO dbo.DeletedEmp
SELECT d.col1, d.col2, ...
FROM deleted d
WHERE empid not in (SELECT empid FROM inserted);
/*
--tests
DELETE FROM dbo.Employees
WHERE empid = 9
SELECT * FROM dbo.DeletedEmp;
*/
You should check both of your tables Employees and DeletedEmp columns have same column data-type. (data-definition)
Check any columns with char and varchar have same length. Char(n) and VarChar(n), where n is the length of string.
Error String or binary data would be truncated is generally when length of the string to be inserted is more than the target's table column can accommodate.
I'm converting a stored procedure in some software I'm maintaining from SQL Server SQL to Informix SQL, and problems are abundant.
Basically I'm converting each section line-by-line until I have the whole thing converted.
I have the following CREATE PROCEDURE:
CREATE PROCEDURE ifxdbase:dc_buildSP (WorkID INT, CompNo smallint)
CREATE TEMP TABLE Items
(
Code smallint,
Qty int,
Total int
);
INSERT INTO Items
SELECT
tblDetails.code,
tblDetails.quantity,
tblHead.quantity
FROM
tblHead
INNER JOIN tblDetails ON (tblDetails.compno = tblDetails.compno AND tblDetails.id_num = tblHead.id_num)
WHERE tblHead.compno = CompNo AND tblHead.id_num = WorkID;
--ORDER BY tblDetails.code;
DROP TABLE Items;
END PROCEDURE
As it stands, this works fine, but when I uncomment the line --ORDER BY tblDetails.seqno; (and remove the semicolon from the previous line) I get a "-201 A syntax error has occurred" error.
Basically tblHead is a series of order headers and tblDetails is a table of the details of each of those orders. Selecting and joining the data works fine, trying to order it fails.
Ordering should work with anything from the original SELECT, IIRC, so I can't see what could be going wrong, here...
As stated here:
..... not all clauses and options of
the SELECT statement are available for
you to use in a query within an
INSERT statement. The following SELECT
clauses and options are not supported
by Informix in an INSERT statement:
FIRST and INTO TEMP
ORDER BY and UNION
so ORDER BY is not supported in the INSERT command in Informix.
I don't have something to test right now, but you could try something like this, as a workaround:
INSERT INTO Items
SELECT code, dQuantity, hQuantity
FROM (
SELECT
tblDetails.code,
tblDetails.quantity dQuantity,
tblHead.quantity hQuantity
FROM
tblHead
INNER JOIN tblDetails ON (tblDetails.compno = tblDetails.compno AND tblDetails.id_num = tblHead.id_num)
WHERE tblHead.compno = CompNo AND tblHead.id_num = WorkID;
ORDER BY tblDetails.code
);
I've written a stored procedure as following:
CREATE PROC spSoNguoiThan
#SNT int
AS
begin
IF not exists (select column_name from INFORMATION_SCHEMA.columns where
table_name = 'NhanVien' and column_name = 'SoNguoiThan')
ALTER TABLE NhanVien ADD SoNguoiThan int
else
begin
UPDATE NhanVien
SET NhanVien.SoNguoiThan = (SELECT Count(MaNguoiThan)FROM NguoiThan
WHERE MaNV=NhanVien.MaNV
GROUP BY NhanVien.MaNV)
end
SELECT *
FROM NhanVien
WHERE SoNguoiThan>#SNT
end
GO
Then I get the error :
Server: Msg 207, Level 16, State 1, Procedure spSoNguoiThan, Line 12
Invalid column name 'SoNguoiThan'.
Server: Msg 207, Level 16, State 1, Procedure spSoNguoiThan, Line 15
Invalid column name 'SoNguoiThan'.
Who can help me?
Thanks!
When the stored proc is parsed during CREATE the column does not exist so you get an error.
Running the internal code line by line works because they are separate. The 2nd batch (UPDATE) runs because the column exists.
The only way around this would be to use dynamic SQL for the update and select so it's not parsed until EXECUTE time (not CREATE time like now).
However, this is something I really would not do: DDL and DML in the same bit of code
I ran into this same issue and found that in addition to using dynamic sql I could solve it by cross joining to a temp table that had only one row. That caused the script compiler to not try to resolve the renamed column at compile time. Below is an example of what I did to solve the issue without using dynamic SQL
select '1' as SomeText into #dummytable
update q set q.ValueTXT = convert(varchar(255), q.ValueTXTTMP) from [dbo].[SomeImportantTable] q cross join #dummytable p