Reputation: 19
ALTER PROCEDURE [dbo].[Create_Subjects]
@Subj_ID nvarchar(9)
AS
DECLARE @First3Digits nvarchar(3);
DECLARE @Result int;
-- Fetching the first 3 digits of the subject
SET @First3Digits = SUBSTRING(@Subj_ID,1,3);
-- Check if view is present or not
IF EXISTS (SELECT 1 FROM sys.views WHERE Name = @First3Digits)
BEGIN
PRINT 'View exists'
-- checking if the subject is present in the view
IF EXISTS (SELECT 1 FROM @First3Digits WHERE SubjectName = @Subj_ID)
BEGIN
SET @Result = 1;
END
ELSE
BEGIN
SET @Result = 0;
END
END
ELSE
BEGIN
-- Create a view as view doesn't exist
EXEC('create view' + @First3Digits
+ 'as
(select SubjectName from dbo.Subjects where SubjectName like '+@First3Digits+'%'+');')
SET @Result = 0;
PRINT 'view does not exist'
END
PRINT @First3Digits
GO;
In the above code I am getting issues on the line
IF EXISTS (SELECT 1 FROM @First3Digits WHERE SubjectName = @Subj_ID)
Please help me to fix this issue.
Upvotes: 1
Views: 259
Reputation: 27201
The line:
IF EXISTS (SELECT 1 FROM @First3Digits WHERE SubjectName = @Subj_ID)
is broken because @First3Digits
is the name of a table (I assume - even though its only nvarchar(3)
!) and cannot be used directly in a query like that, instead you need to use dynamic SQL, specifically sp_executesql
as follows:
PRINT 'View exists'
declare @Sql nvarchar(max);
set @Sql = 'select @Result = case when exists (select 1 from dbo.' + quotename(@First3Digits) + ' where SubjectName = ''' + @Subj_ID + ''') then 1 else 0 end';
execute sp_executesql @Sql, N'@Result bit out', @Result = @Result out;
-- @Result is now set as required
Note the use of quotename
to protect against SQL injection.
As an aside, on the face of it, your design looks highly in need of improvement. Creating a view per Subject
(whatever that actually is) seems flawed, prone to maintenance issues and scalability issues. There is probably a better way.
Upvotes: 2