SQL Alter table within an IF ELSE statement - sql

I have the following sql:
DECLARE #Variable1 VARCHAR(10)
SET #Variable1 = 'YES
IF #Variable1 = 'YES'
BEGIN
alter table #Tempfile add Newcolumn varchar(10)
UPDATE #Tempfile
SET Newcolumn ='J'
FROM #Tempfile
INNER JOIN OtherTable
ON #Tempfile.SPLPKD = OtherTable.SPLPKD
AND #Tempfile.SPLHNR = OtherTable.SPLHNR
PRINT('Variable was Yes')
END
ELSE
BEGIN
PRINT('Variable was NO!!')
END
Now as long as the #variable1 is YES everthing goes as expected.
But when #Variable1 is NO, I get the following error message:
Msg 207, Level 16, State 1, Line 201 Invalid column name 'Newcolumn'.
Which for me looks very strange cause the I thought the IF would prevent to check the code within that statement.
What am I doing wrong here?

Your extra column does not exist when you start executing the script, the UPDATE is being validated and decide that the column doesn't exists. This check can be avoided by using embedded sql:
IF #Variable1 = 'YES'
BEGIN
alter table #Tempfile add Newcolumn varchar(10)
EXECUTE('UPDATE #Tempfile
SET Newcolumn =''J''
FROM #Tempfile
INNER JOIN OtherTable
ON #Tempfile.SPLPKD = OtherTable.SPLPKD
AND #Tempfile.SPLHNR = OtherTable.SPLHNR
PRINT(''Variable was Yes'')')
END
ELSE
BEGIN
PRINT('Variable was NO!!')
END

Related

Implicit conversion of varchar value to varchar cannot be performed due to a collation conflict

When I try to change the collation of a column in SQL Server I get the following error.
Implicit conversion of varchar value to varchar cannot be performed because the collation of the value is unresolved due to a collation conflict between "Latin1_General_CS_AI" and "SQL_Latin1_General_CP1_CI_AS" in add operator.
Below is the specific query I am trying to run. I get the same error regardless of whether I run the query manually or use the GUI.
ALTER TABLE myTable ADD myColumn NVARCHAR(152) COLLATE Latin1_General_CS_AI NULL;
Edit:
Upon doing some more digging I think the issue may occur when sql server tries to rebuild one of the triggers on the table. Partially shown below... I apologize for the awful formatting but I can't seem to get it to format properly
Edit 2: Thanks for fixing my formatting! :) The line at the bottom of the code section below seems to be where the error is originating.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER trigger [dbo].[payee_audit_update_trigger] on [dbo].[payee] for update as
begin
set nocount on
declare #userId varchar(50), #sqlStatement varchar(255), #appId int, #transactionId int, #insertChangedValues varchar(255), #auditEnabled char(1), #timezoneOffsetMinutes int
exec AuditGetSessionInfo ##rowcount, #userId output, #sqlStatement output, #appId output, #transactionId output, #insertChangedValues output, #auditEnabled output, #timezoneOffsetMinutes output
if (#auditEnabled = 'N')
return
declare #auditDate datetime
set #auditDate = dateadd(MINUTE, #timezoneOffsetMinutes, getutcdate())
insert into audit_log_tx (company_id, application_id, change_date_time, id, table_name, transaction_id, user_id, sql_statement, primary_key_crc, primary_key_values, changed_values)
select inserted.company_id,#appId, #auditDate, dbo.AuditGetRowId(newId()), 'payee', #transactionId, #userId, #sqlStatement, binary_checksum(rtrim(inserted.id)), rtrim(inserted.id),
case when (inserted.company_id = deleted.company_id) or (inserted.company_id is null and deleted.company_id is null) then '' else 'company_id|' + case when deleted.company_id is null then '<null>' else rtrim(deleted.company_id) end + '|' + case when inserted.company_id is null then '<null>' else rtrim(inserted.company_id) end + '^' end + ...
------
case when (inserted.w4_status = deleted.w4_status) or (inserted.w4_status is null and deleted.w4_status is null) then '' else 'w4_status|' + case when deleted.w4_status is null then '<null>' else rtrim(deleted.w4_status) end + '|' + case when inserted.w4_status is null then '<null>' else rtrim(inserted.w4_status) end + '^' end +
how about forcing the collation in the query:
if for example is happening at field1 = field2
you can force it like:
field1 collate Latin1_General_CI_AS = field1 collate Latin1_General_CI_AS

SQL IF/ELSE Statement

I'm struggling to understand why the below SQL will not work. I've put a comment (----------Fine up to Here), which is where SQL Server will accept the code when I parse/save the Store proceedure.
The bit below that, it will not take. Still new to SQL so any help would be great.
The error I receive is, Incorrect syntax near the keyword 'ELSE'. The "ELSE" being the one under the comment I mentioned above.
What I also don't understand is, If I change the IF and the BEGIN round, SQL accepts it (below)? I thought ELSE IF was not possible.
----------Fine up to Here
ELSE
IF (#GrabTypeID = '')
BEGIN
****************************************
Code below
**************************************
IF (#GrabtypeID NOT IN (SELECT GRABTYPEID FROM Mytable) AND #GrabtypeID != '') OR
(#Variable1 NOT IN (SELECT ID FROM Mytable) AND #Variable1 !='')
BEGIN
SELECT #ErrorMessage ='The GrabTypeID or the ID is an invalid value'
RAISERROR (#ErrorMessage, 16, 1)
PRINT 'Invalid Parameters passed Through'
RETURN
END
ELSE
BEGIN
IF (#GrabtypeID ! ='')
TRUNCATE TABLE Datatable1
TRUNCATE TABLE Datatable2
INSERT Datatable1
SELECT * FROM Referencetable1
INSERT Datatable2
SELECT * FROM REFERENCETABLE2
END
----------Fine up to Here
ELSE
BEGIN
IF (#GrabTypeID = '')
TRUNCATE TABLE Datatable1
TRUNCATE TABLE Datatable2
INSERT Datatable1
SELECT * FROM REFERENCETABLE1 WHERE CATEGORY = 4
INSERT Datatable2
SELECT * FROM REFERENCETABLE2 WHERE CATEGORY = 4
END
GO
Your format is a little weird. You could make it work the way you have it, but I think it would be better to use this format:
IF expression
BEGIN
SELECT
END
ELSE IF expression
BEGIN
SELECT
END
ELSE IF expression
BEGIN
SELECT
END
Specifically, change this:
ELSE
BEGIN
IF (#GrabtypeID ! ='')
To this (in both places):
ELSE IF (#GrabtypeID ! ='')
BEGIN

if condition not working

I want to show a message if record is not in the table.
I wrote this small piece of code, but it's giving me an error.
create procedure abc(#id varchar(25))
as
declare #msg1 as varchar(55)
begin
select id,fname,lname from student where id=#id
--up to this is working correctly
--for showing msg i write down this lince of code
if id=#id
select #msg=“correct record“
else
select #msg=“record not found“
end
end
Add an EXISTS check instead of selecting the records
IF EXISTS ( select 1 from student where id=#id)
BEGIN
SET #msg = 'correct record'
END
ELSE
BEGIN
SET #msg = 'incorrect record'
END
Are you trying to return the value of #msg? If yes, add SELECT #msg at the end.
Use single quotes not double. And check for any results with ##rowcount
create procedure abc(#id varchar(25))
as
begin
select id,fname,lname from student where id=#id
if ##rowcount > 0
select 'correct record' as msg
else
select 'record not found' as msg
end
end

Stored Procedure that accepts all table fields and updates those values

I'm working through a couple practice questions and I've run across this problem, I keep getting an error when trying to execute the procedure that says
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'Procedure'."
Can someone please help?
Write a procedure UpdateTitle that accepts all the Title table columns and will update the title with those values. Raise error messages for the following: The ISBN does not exist The Category and/or Publisher Codes are not valid.
Create PROCEDURE UpdateTitle (#ISBN char(10), #SuggestedPrice smallmoney,#NumberInStock smallint,#PublisherCode int,#CategoryCode int)
AS
BEGIN
IF #ISBN is null or #CategoryCode is null or #PublisherCode is null
BEGIN
RAISERROR ('ISBN,CategoryCode, or PublisherCode is not valid please enter valid data',16,1)
END
ELSE
BEGIN
IF (SELECT COUNT(*) FROM Title WHERE ISBN = #ISBN) = 0
BEGIN
RAISERROR ('ISBN does not exist.',16,1)
END
ELSE
BEGIN
SELECT 'Table Sucessfully Updated.';
UPDATE Title
SET SuggestedPrice = #SuggestedPrice
WHERE ISBN = #ISBN;
BEGIN
IF (SELECT COUNT(*) FROM Title WHERE ISBN = #ISBN) = 0
BEGIN
RAISERROR ('ISBN does not exist.',16,1)
END
ELSE
BEGIN
SELECT 'Table Sucessfully Updated.';
UPDATE Title
SET NumberInStock = #NumberInStock
WHERE ISBN = #ISBN;
END
BEGIN
IF (SELECT COUNT(*) FROM Title WHERE ISBN = #ISBN) = 0
BEGIN
RAISERROR ('ISBN does not exist.',16,1)
END
ELSE
BEGIN
SELECT 'Table Sucessfully Updated.';
UPDATE Title
SET PublisherCode = #PublisherCode
WHERE ISBN = #ISBN;
END
BEGIN
IF (SELECT COUNT(*) FROM Title WHERE ISBN = #ISBN) = 0
BEGIN
RAISERROR ('ISBN does not exist.',16,1)
END
ELSE
BEGIN
SELECT 'Table Sucessfully Updated.';
UPDATE Title
SET CategoryCode = #CategoryCode
WHERE ISBN = #ISBN;
END
END
END
END
END
END
END
GO
Then
Execute Procedure UpdateTitle #ISBN ='1021031040', #suggestedproce ='40' , #NumberInStock ='10', #PublisherCode = '200', #CategoryCode = '1'
Execute Procedure UpdateTitle ...
Should be:
EXEC dbo.UpdateTitle ...
Some other comments:
ISBN is no longer limited to 10 characters (this change happened in 2007, if you believe WikiPedia).
Always use the schema prefix when creating or referencing objects.
You only need to check that the ISBN is valid once. And you shouldn't do so using a count IMHO, especially since - presumably - that is the key and it could only ever return 0 or 1 anyway.
You shouldn't select "update successful" and then perform the update. You should make sure the update was successful before telling the user it was successful.
There is no reason to separate this out into multiple updates either.
Please be liberal with carriage returns, indenting and whitespace. The value in readability is worth the extra cost in typing it (since you only type it once, but you will read it multiple times).
Use RETURN; as an exit mechanism so that you don't have to nest IF and ELSE multiple times.
Always use SET NOCOUNT ON; at the beginning of your procedures.
You probably want to customize the message to tell the user which parameter(s) were invalid.
Oh yeah, and please future-proof your code by using semi-colons to terminate statements.
Here is a much more concise version that satisfies all of your requirements:
CREATE PROCEDURE dbo.UpdateTitle
#ISBN CHAR(10),
#SuggestedPrice SMALLMONEY,
#NumberInStock SMALLINT,
#PublisherCode INT,
#CategoryCode INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #msg VARCHAR(255);
IF #ISBN IS NULL OR #CategoryCode IS NULL OR #PublisherCode IS NULL
BEGIN
SELECT #msg = 'The following parameter(s) were invalid:'
+ CASE WHEN #ISBN IS NULL THEN ' #ISBN' ELSE '' END
+ CASE WHEN #CategoryCode IS NULL THEN ' #CategoryCode' ELSE '' END
+ CASE WHEN #PublisherCode IS NULL THEN ' #PublisherCode' ELSE '' END;
RAISERROR (#msg, 11, 1);
RETURN;
END
IF NOT EXISTS (SELECT 1 FROM dbo.Title WHERE ISBN = #ISBN)
BEGIN
SET #msg = 'ISBN %s does not exist.';
RAISERROR(#msg, 11, 1, #ISBN);
RETURN;
END
BEGIN TRY
UPDATE dbo.Title
SET SuggestedPrice = #SuggestedPrice,
NumberInStock = #NumberInStock,
PublisherCode = #PublisherCode,
CategoryCode = #CategoryCode
WHERE ISBN = #ISBN;
SELECT 'Update successful.';
END TRY
BEGIN CATCH
SET #msg = ERROR_MESSAGE();
RAISERROR(#msg, 11, 1);
END CATCH
END
GO

T-SQL error object exists when separated in if/else blocks

I get the error: Msg 2714, Level 16, State 1, Line 16
There is already an object named '#mytemptable' in the database.
There are ways around it, but wonder why this happens. Seems like SQL Server is verifying both blocks of the if/else statement?
declare #choice int
select #choice = 1
if #choice = 1
begin
select 'MyValue = 1' AS Pick into #my_temp_table
end
else
begin
select 'MyValue <> 1' AS Pick into #my_temp_table
end
select * from #my_temp_table
drop table #my_temp_table
If the tables have different names, it works. Or if I create the temp table and use Insert Into... statements that works as well.
See here: What is deferred name resolution and why do you need to care?
basically you need to ceate the table first
So what is happening is that beginning with SQL server 7 deferred name resolution was enabled for real tables but not for temporary tables. If you change the code to use a real table instead of a temporary table you won’t have any problem
Here is another way
declare #choice int
select #choice = 1
declare #Value varchar(100)
if #choice = 1
select #Value = 'MyValue = 1'
else
select #Value = 'MyValue <> 1'
select #Value AS Pick into #my_temp_table
select * from #my_temp_table
drop table #my_temp_table
Try this:
declare #choice int
select #choice = 1
CREATE TABLE #my_temp_table(
Pick varchar(25)
)
if #choice = 1
begin
INSERT INTO #my_temp_table
select 'MyValue = 1'
end
else
begin
INSERT INTO #my_temp_table
select 'MyValue <> 1'
end
select * from #temptable
drop table #temptable
EDIT Sorry, I see that you tried this and the question was WHY does this happen. It is because SQL Server parses the stored procedure when it is created and checks for naming conflicts.