tsql dynamic sql best approach - sql-server-2008

The dynamica query I have below works but wondering if what I have below can be optimized or if there is a better way of doing it.
I have a web form where the user enters a location and Date Collected. For the date collected, I have a From Date Collected and To Date Collected. The user an leave the To date collected blank in which case it will do anything greater than the From Date Collected.
Note how I am doing the IS NOT NULL and 1=1 below. Also wondering if a dynamic SQL is the best approach or if there is a simpler way of doing this.
DECLARE #sql varchar(max);
SET #sql = 'SELECT * from tblProgram WHERE 1=1'
IF (#Location IS NOT NULL)
BEGIN
SET #sql = #sql + ' AND Location = ' + #Location
END
IF (#FromDateCollected IS NOT NULL AND #ToDateCollected IS NOT NULL)
BEGIN
SET #sql = #sql + ' AND pw.DateCollected >= ' + QUOTENAME(convert(varchar, #FromDateCollected,101),'''')
+ ' AND pw.DateCollected <= ' + QUOTENAME(convert(varchar, #ToDateCollected,101),'''')
END
ELSE IF (#FromDateCollected IS NOT NULL AND #ToDateCollected IS NULL)
BEGIN
SET #sql = #sql + ' AND pw.DateCollected >= ' + QUOTENAME(convert(varchar, #FromDateCollected,101),'''')
END
exec(#sql)

Well you can do as ta.speot.is comments use static SQL and do
WHERE x is null or x > date_column?
However if you insist on using Dynamic SQL you should use a parameterized SQL statement using sp_executeSQL
Its easier to read, you don't have to use quotename, and you're protected from SQL Injection
DECLARE #Location int
DECLARE #FromDateCollected datetime
DECLARE #ToDateCollected datetime
SET #ToDateCollected = '1/02/2012'
DECLARE #sql nvarchar(max)
DECLARE #ParmDefinition nvarchar(max)
SET #ParmDefinition = N'#Location int , #FromDateCollected datetime, #ToDateCollected datetime ';
SET #sql = N'SELECT * from tblProgram WHERE 1=1'
IF (#Location IS NOT NULL)
BEGIN
SET #sql = #sql + N' AND Location = #Location'
END
IF (#FromDateCollected IS NOT NULL AND #ToDateCollected IS NOT NULL)
BEGIN
SET #sql = #sql + N' AND pw.DateCollected >= #FromDateCollected '
+ N' AND pw.DateCollected <= #ToDateCollected '
END
ELSE IF (#FromDateCollected IS NOT NULL AND #ToDateCollected IS NULL)
BEGIN
SET #sql = #sql + N' AND pw.DateCollected >= #FromDateCollected'
END
exec sp_executesql #SQL, #ParmDefinition, #Location = #Location,
#FromDateCollected = #FromDateCollected,
#ToDateCollected = #ToDateCollected
DEMO

Related

how to convert MSSQL Stored Procedure to Mysql SP using 'With' Keyword in mysql?

this is my Stored Procedure of MSSQL and I want to be convert this SP to MySQL,but i cant understand what to used instead of 'with' keyword in MySql so any one help me ??? Thanx in Advance!!!!!
ALTER PROCEDURE [dbo].[TPortRateOnKm_SP_List]
#qtype varchar(MAX) = NULL,
#query varchar(MAX)= NULL,
#Sortname varchar(MAX) =NULL,
#sortorder varchar(MAX) =NULL ,
#PageNo int,
#RecordsPerPage int,
#likesearch int
AS
BEGIN
DECLARE #temp INT;
DECLARE #qry varchar(MAX) = '';
DECLARE #qry1 varchar(MAX) = '';
set #temp = (#PageNo - 1) * #RecordsPerPage
If #query is not null and #query <> ''
Begin
Set #qry1= ' Where '+ #query
End
Else
Begin
Set #qry1= ''
End
If #query is not null and #query <> ''
Begin
Set #query= ' Where ('+ #query + ') and (RowNo > ' +
cast(((#PageNo-1) *#RecordsPerPage) as varchar) + ' AND RowNo <= '
+ cast(#PageNo * #RecordsPerPage as varchar)+ ') '
End
Else
Begin
Set #query= ' Where (RowNo > ' + cast(((#PageNo-1) *#RecordsPerPage) as varchar) + ' AND RowNo <= ' + cast(#PageNo * #RecordsPerPage as varchar)+ ') '
End
If #sortorder is not null and #sortorder <> ''
Begin
Set #sortorder= ' Order By '+ #sortorder
End
Else
Begin
Set #sortorder= ' ORDER BY VehicleId'
End
here is 'With' Keyword
set #qry = 'Set dateformat dmy ;WITH CustomTable as
(Select ROW_NUMBER() OVER ( '+ #sortorder+') as RowNo,A.* From
(select Convert(varchar,T.WefDate,103) As WefDate,T.VehicleId as
VehicleId,V.VehicleNo as VehicleNo,T.StartKm,T.EndKm,T.Rate from
TrnRateOnKmRange T left outer join MasterVehicle V on
V.VehicleId=T.VehicleId) A '
Set #qry= #qry + #qry1
Set #qry= #qry + ' )
SELECT CAST(RowNo AS INT) as
RowNo,WefDate,VehicleId,VehicleNo,StartKm,EndKm,Rate
FROM CustomTable'
Set #qry=#qry + #query + #sortorder
EXECUTE (#qry)
END
can any one do this ??

Variable has unexpected NULL value in dynamic SQL

I have searched high and low, without finding an answer. So I hope that you guys n girls can help me on my way:
I cant figure out why #old_comment is NULL when I use it in "SET #new_comment...", but it returns a fine value when I use it in the outputparameter "SET #commentOldOUT..."
CREATE PROCEDURE [dbo].[SP_NY_KOMMENTAR]
#tabel NVARCHAR(100),
#id INT,
#comment NVARCHAR(1000) = NULL,
#commentOldOUT NVARCHAR(1000) = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #user NVARCHAR(30);
DECLARE #date NVARCHAR(10);
DECLARE #new_id VARCHAR(100);
DECLARE #new_comment NVARCHAR(MAX);
DECLARE #old_comment NVARCHAR(MAX);
DECLARE #old_comm NVARCHAR(MAX);
DECLARE #old NVARCHAR(MAX);
DECLARE #q2 NVARCHAR(MAX);
SET #new_id = (SELECT CAST(#id AS VARCHAR(100)));
SET #user = (SELECT ORIGINAL_LOGIN());
SET #date = (SELECT CONVERT(DATE,GETDATE()));
SET #old = 'SELECT comment FROM '+ #tabel +' WHERE id = ' + #ny_id;
EXEC sp_executesql
#query = #old,
#params = N'#old_comm NVARCHAR(MAX) OUTPUT',
#old_com = #old_comm OUTPUT;
SET #old_comment = (SELECT #old_comm);
SET #commentOldOUT = #old_comment;
SET #new_comment = COALESCE(#old_comment + CHAR(13),'') + '[' + #user + ' ' + #date + '] ' + #comment;
SET #q2 = N'UPDATE ' + #tabel + ' SET comment = ''' + #new_comment + ''' WHERE id = ' + #ny_id;
EXEC (#q2);
END
Sorry, I tried your query but for me it works fine! Have you tried to "debug" your query? You can see the value of every variable when in debug. (The green arrow in SQL Server 2008)
I'm guessing that you didn't pass a value explicitly for the #comment parameter? If so, the problem would be here:
SET #new_comment = COALESCE(#old_comment + CHAR(13),'') + '[' + #user + ' ' + #date + '] ' + #comment;
The parameter #comment has a default value of NULL and concatenating anything with NULL results in NULL. That would explain why #old_comment, #user and #date all have values, but when it put it all together then #new_comment is NULL. This would be a better default value:
#comment NVARCHAR(1000) = '',
And your code as written is a bit messy, I assume that #old_comment and #commentOldOUT are only for debugging purposes? I don't see why you don't use #old_comm directly.
Finally, if you're working with dynamic SQL then I strongly recommend adding a debugging parameter to print out your SQL strings easily. It's a very useful troubleshooting tool, especially if you don't have SSMS available.
Well I can now see that I did several things wrong, below is the new, and now working, stored procedure:
CREATE PROCEDURE [dbo].[SP_NY_KOMMENTAR]
#tabel NVARCHAR(100),
#id INT,
#comment NVARCHAR(1000) = NULL
AS
IF #comment IS NOT NULL
BEGIN
SET NOCOUNT ON;
DECLARE #user NVARCHAR(30);
DECLARE #date NVARCHAR(10);
DECLARE #SQLSelect nvarchar(500);
DECLARE #ParmSelect nvarchar(500);
DECLARE #old_comment NVARCHAR(MAX);
DECLARE #old_commentOUT NVARCHAR(MAX);
DECLARE #new_comment NVARCHAR(MAX);
DECLARE #SQLUpdate nvarchar(500);
DECLARE #ParmUpdate nvarchar(500);
SET #user = (SELECT ORIGINAL_LOGIN());
SET #date = (SELECT CONVERT(DATE,GETDATE()));
SET #SQLSelect = N'SELECT #old_commentOUT = kommentar FROM ' + QUOTENAME(#tabel) + ' WHERE id = #id';
SET #ParmSelect = N'#id INT, #old_commentOUT NVARCHAR(MAX) OUTPUT';
EXEC sp_executesql
#SQLSelect,
#ParmSelect,
#id = #id,
#old_commentOUT = #old_comment OUTPUT;
SET #old_comment = (SELECT #old_comment);
SET #new_comment = COALESCE(#old_comment + CHAR(13) + CHAR(10),'') + '[' + #user + ' ' + #date + '] ' + #comment;
SET #SQLUpdate = N'UPDATE ' + QUOTENAME(#tabel) + ' SET kommentar = #new_comment WHERE id = #id';
SET #ParmUpdate = N'#id INT, #new_comment NVARCHAR(MAX)';
EXEC sp_executesql
#SQLUpdate,
#ParmUpdate,
#id = #id,
#new_comment = #new_comment;
END
For example I weren't using parameterbinding correct, after that I tried to bind tabelnames as a parameter...

How to get all the transaction logs (insert update delete) for a specific table in SQL Server 2008

I want to get all the transactions applied on a specific table in SQL Server 2008.
I found the last time a table was updated using this script:
SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID( 'DBName')
AND OBJECT_ID=OBJECT_ID('tableName')
I want to know all the transactions (Inserts, Updates, Deletes) for that table, and their datetime, and the query applied.
What is the best way to do this?
The only way to do this in a reasonable amount of time is to use a third party tool(as Martin said in first comment) such as ApexSQL Log that can read transaction log and get the information you need.
Note that in order for this to work your database has to be in a full recovery mode because that’s when SQL Server logs full transaction details that can be reconstructed later.
Another option is to investigate how to use undocumented fn_dblog function but this will take you a lot more time and you won’t be able to read detached logs or transaction log backups.
creating a trigger which will create a new table Emp_audit and add new tuples to it whenever any change is made to table employee
create trigger my_trigger on Employees
AFTER INSERT, UPDATE, DELETE
AS
DECLARE #What varchar(30);
DECLARE #Who varchar(30);
DECLARE #for int;
DECLARE #At time;
DECLARE #COUNTI int;
DECLARE #COUNTD int;
select #COUNTI = COUNT(*) from inserted;
select #COUNTD = COUNT(*) from deleted;
set #Who = SYSTEM_USER;
set #At = CURRENT_TIMESTAMP;
if( #COUNTD = 0 and #COUNTI = 1)
begin
set #What = 'insert';
select #for = EmployeeID from inserted i;
end
else
begin
if( #COUNTD = 1 and #COUNTI = 0)
begin
set #What = 'delete';
select #for = EmployeeID from deleted i;
end
else
begin
set #What = 'update';
select #for = EmployeeID from inserted i;
end
end
INSERT INTO EMP_Audit Values (#What, #Who, #for, #At);
You would be much better off setting up auditing for this need rather than trying to extract this information retrospectively from the transaction log.
If you are on Enterprise Edition you could use the built in SQL Server Audit functionality, otherwise it should be relative straight forward to log the desired information via triggers.
You could create your own transaction logs
Step 1: Create your own table for transaction logs
CREATE TABLE [dbo].[TransactionLogs](
[TransactionLogID] [bigint] IDENTITY(1,1) NOT NULL,
[Query] [nvarchar](max) NOT NULL,
[DateCreated] [datetime] NOT NULL,
CONSTRAINT [PK_TransactionLogs] PRIMARY KEY CLUSTERED
(
[TransactionLogID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Step 2: Create stored procedure that create logs. (Note: Replace YourTablePKColumn with your table primary key column.)
create procedure [dbo].[sp_CreateQueryLogs]
(
#Query nvarchar(max) = null output,
#TableName nvarchar(100),
#YourTablePKColumn nvarchar(30),
#QueryTypeID tinyint --0 insert, 1 update, 2 delete
)
as
begin
declare #object_id bigint, #column_name nvarchar(100), #collation_name nvarchar(50), #column_name_id nvarchar(100) = null, #column_names nvarchar(max) = '', #column_values nvarchar(max) = '', #column_names_create nvarchar(max) = '', #values nvarchar(max) = '', #user_type_id int, #max_length nvarchar(10), #type_name nvarchar(50), #CreateTempTable nvarchar(max) = '', #is_nullable bit, #value nvarchar(max) = ''
create table #tmpValues(ColumnValues nvarchar(max))
insert into #tmpValues(ColumnValues)
exec('select CAST ( ( select * from ' + #TableName + ' where YourTablePKColumn = ' + #YourTablePKColumn + '
FOR XML PATH(''tr''), TYPE
) AS NVARCHAR(MAX) )')
select #values = ColumnValues from #tmpValues
if #QueryTypeID = 0 --insert
set #Query = 'insert into ' + #TableName + '('
else if #QueryTypeID = 1 --update
set #Query = 'update ' + #TableName + ' set '
else if #QueryTypeID = 2 --dalete
set #Query = 'delete ' + #TableName + ' '
select #object_id = object_id from sys.tables where name = #TableName
if not cursor_status('local','columnCursor') <= -1
begin
close columnCursor;
deallocate columnCursor;
end
declare columnCursor cursor local for
select name, user_type_id, convert(nvarchar(10), max_length), is_nullable from sys.columns where object_id = #object_id order by column_id ;
open columnCursor;
fetch next from columnCursor
into #column_name, #user_type_id, #max_length, #is_nullable;
while ##FETCH_STATUS = 0
begin
select #type_name = name, #collation_name = collation_name from sys.types where user_type_id = #user_type_id
if #column_name_id is null
set #column_name_id = #column_name
else
begin
set #column_names += #column_name + ', '
declare #value_keys_start nvarchar(max) = '<' + #column_name + '>', #value_keys_end nvarchar(max) = '</' + #column_name + '>'
if charindex(#value_keys_start,#values,1) = 0
begin
if #QueryTypeID = 0 --insert
set #column_values += 'null,'
else if #QueryTypeID = 1 --update
set #column_values += #column_name + ' = null,'
end
else
begin
if #QueryTypeID = 0 --insert
if #collation_name is null and not (#type_name like '%date%' or #type_name like '%time%')
set #column_values += substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))) + ','
else if #type_name like '%date%' or #type_name like '%time%'
set #column_values += '''' + replace(substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))),'T',' ') + ''','
else
set #column_values += '''' + replace(substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))),'''','''''') + ''','
else if #QueryTypeID = 1 --update
if #collation_name is null and not (#type_name like '%date%' or #type_name like '%time%')
set #column_values += #column_name + '=' + substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))) + ','
else if #type_name like '%date%' or #type_name like '%time%'
set #column_values += #column_name + '=' + '''' + replace(substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))),'T',' ') + ''','
else
set #column_values += #column_name + '=' + '''' + replace(substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))),'''','''''') + ''','
end
end
fetch next from columnCursor
into #column_name, #user_type_id, #max_length, #is_nullable;
end
if not cursor_status('local','columnCursor') <= -1
begin
close columnCursor;
deallocate columnCursor;
end
if #QueryTypeID = 0 --insert
set #Query += substring(#column_names,1,len(#column_names) - 1) + ')
values (' + substring(#column_values,1,len(#column_values) - 1) + ')'
else if #QueryTypeID = 1 --update or delete
set #Query += substring(#column_values,1,len(#column_values) - 1) + ' where YourTablePKColumn = ' + #YourTablePKColumn
else
set #Query += ' where YourTablePKColumn = ' + #YourTablePKColumn
end
Step 3: Created trigger to table you want to have transaction logs
CREATE TRIGGER trg_MyTrigger ON YouTableName
AFTER INSERT, DELETE, UPDATE
AS
BEGIN
SET NOCOUNT ON;
declare #TableName nvarchar(100) = 'YouTableName', #Query nvarchar(max), #QueryTypeID tinyint, #YourTablePKColumn nvarchar(30)
if exists(select * from deleted) and exists(select * from inserted)
begin
set #QueryTypeID = 1
if not cursor_status('local','updatedCursor') <= -1
begin
close updatedCursor;
deallocate updatedCursor;
end
declare updatedCursor cursor local for
select cast(YourTablePKColumn as nvarchar(30)) from inserted;
open updatedCursor;
fetch next from updatedCursor
into #YourTablePKColumn;
while ##FETCH_STATUS = 0
begin
exec dbo.sp_CreateQueryLogs #Query = #Query output, #TableName = #TableName, #YourTablePKColumn = #YourTablePKColumn, #QueryTypeID = #QueryTypeID
insert into TransactionLogs
(Query, DateCreated)
values (#Query,getdate())
fetch next from updatedCursor
into #YourTablePKColumn;
end
if not cursor_status('local','updatedCursor') <= -1
begin
close updatedCursor;
deallocate updatedCursor;
end
end
else if exists(select * from deleted) and not exists(select * from inserted)
begin
set #QueryTypeID = 2
if not cursor_status('local','deletedCursor') <= -1
begin
close deletedCursor;
deallocate deletedCursor;
end
declare deletedCursor cursor local for
select cast(YourTablePKColumn as nvarchar(30)) from deleted;
open deletedCursor;
fetch next from deletedCursor
into #YourTablePKColumn;
while ##FETCH_STATUS = 0
begin
exec dbo.sp_CreateQueryLogs #Query = #Query output, #TableName = #TableName, #YourTablePKColumn = #YourTablePKColumn, #QueryTypeID = #QueryTypeID
insert into TransactionLogs
(Query, DateCreated)
values (#Query,getdate())
fetch next from deletedCursor
into #YourTablePKColumn;
end
if not cursor_status('local','deletedCursor') <= -1
begin
close deletedCursor;
deallocate deletedCursor;
end
end
else
begin
set #QueryTypeID = 0
if not cursor_status('local','insertedCursor') <= -1
begin
close insertedCursor;
deallocate insertedCursor;
end
declare insertedCursor cursor local for
select cast(YourTablePKColumn as nvarchar(30)) from inserted;
open insertedCursor;
fetch next from insertedCursor
into #YourTablePKColumn;
while ##FETCH_STATUS = 0
begin
exec dbo.sp_CreateQueryLogs #Query = #Query output, #TableName = #TableName, #YourTablePKColumn = #YourTablePKColumn, #QueryTypeID = #QueryTypeID
insert into TransactionLogs
(Query, DateCreated)
values (#Query,getdate())
fetch next from insertedCursor
into #YourTablePKColumn;
end
if not cursor_status('local','insertedCursor') <= -1
begin
close insertedCursor;
deallocate insertedCursor;
end
end
END
GO

Dynamic SQL concatenation

Having an issue concatenating the following statement.
Basically I want the length column to add inches after but it will not run. I am going to create a function out of this in the future but unable to get past this step. What gives?
declare #column varchar(255)
declare #sql varchar(5000)
declare #additional varchar(500)
set #column = 'length'
set #additional = 'inches'
select #sql = 'select distinct ps.p_c_id, '
select #sql = #sql + #column + ' '+#additional+ ' ' + ' as value'
select #sql = #sql
select #sql = #sql + ' from dbo.Product ps
inner join dbo.ProductAttributes psa on psa.p_s_id = ps.p_s_id
where ps.p_c_id is not null and ' + #column + ' is not null'
exec (#sql)
You are concatenating, what i'm assuming is an int or float value to a string ' inches'...have to cast the "length" value as a varchar...
just select your #sql next time to see the resulting syntax and it should jump out at you. here is changes that should work
BTW...look at implementing EXEC sp_executesql ...makes dynamic sql less suseptable to injection by using parameters, etc... look up in Books OnLine
Sorry...eating Crow...sp_executesql does not protect from injection just improves performance in general...see article MSDN SQL Injection
declare #column varchar(255)
declare #sql varchar(5000)
declare #additional varchar(500)
set #column = 'psa.length'
set #additional = 'inches'
select #sql = 'select distinct ps.p_c_id, '
select #sql = #sql + 'CAST(' + #column + ' AS varchar(10)) + ' + ''' '+#additional+ ''' ' + ' as value'
select #sql = #sql
select #sql = #sql + ' from dbo.Product ps
inner join dbo.ProductAttributes psa on psa.p_s_id = ps.p_s_id
where ps.p_c_id is not null and ' + #column + ' is not null'
--select #sql AS [ExecutableSQL]
exec(#sql)
Your output is;
select distinct ps.p_c_id, length inches as value from dbo.Product ps
inner join dbo.ProductAttributes psa on psa.p_s_id = ps.p_s_id
where ps.p_c_id is not null and length is not null
So it looks like a missing , between length inches assuming you want both;
select #sql = #sql + #column + ','+ #additional+ ' ' + ' as value'

Conversion failed when converting the nvarchar value 'SELECT * FROM

Using Sql Server 2008, developed a view "vw_MasterView" I get this error:
Conversion failed when converting the nvarchar value 'SELECT * FROM VW_MASTERVIEW v WHERE 1=1 AND v.ClinicId = '' to data type int.
when I run the following stored procedure:
USE [xxxxxxx]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ClientSummary1]
#LocationId int,
#startDate datetime,
#endDate datetime,
#userName nvarchar(50)
AS
declare #sql nvarchar(2000);
SET NOCOUNT ON
set #sql = 'SELECT * FROM VW_MASTERVIEW v WHERE 1=1 ';
IF #LocationId is not null
begin
set #sql = #sql + ' AND v.LocationId = ''' + #LocationId + '''';
end
if #userName is not null
begin
set #sql = #sql + ' AND (v.FirstUser = '' OR v.SecondUser = '')' + #userName + '''';
end
if #startDate is not null
begin
set #sql = #sql + ' AND v.FirstVisitDate = ''' + #startDate + '''';
end
if #endDate is not null
begin
set #sql = #sql + ' AND v.LastVisitDate = ''' + #endDate + '''';
end
EXEC(#sql)
I get both the LocationId and userName from a VS2010 application.
Thanks in Advance
When appending strings together in SQL Server, you have to cast non-textual types (such as int) to a textual type (such as varchar):
set #sql = #sql + ' AND v.LocationId = ''' +
cast(#LocationId as varchar(10)) + '''';
-- ^^^^ have to cast ^^ make sure size is big enough
Note that dynamic SQL should not be necessary in the first place. You can just run the query directly with the parameters (I implemented the null checks with the extra or conditions):
SELECT * FROM VW_MASTERVIEW v
WHERE (v.LocationId = #LocationId OR #LocationId is null)
AND (v.FirstUser = #userName OR v.Seconduser = #userName OR #userName is null)
AND (v.FirstVisitDate = #startDate OR #startDate is null)
AND (v.LastVisitDate = #endDate OR #endDate is null)
I may not have the logic right for FirstUser and SecondUser - I took an educated guess from your incomplete code.
Hope this helps!