whether value is repeated in database? - sql

IF EXISTS ( 'SELECT ' +#TextField+','+#ValueField+' FROM ' + #TableName + ' WHERE ' + #TextFieldPara + '=' +#ValueFieldPara + ' ORDER BY ' +#TextField+' ASC;')
BEGIN
SET #Message = #TextField + ' Already Exist...'
END
ELSE
BEGIN
SET #Message = 'TRUE'
END
by using this query i am trying to check in all table whether inserted value for field Repeated or Not.
when i write this query in store procedure i got an error at
IF EXISTS ( 'SELECT ' +#TextField+','+#ValueField+' FROM ' + #TableName + ' WHERE ' + #TextFieldPara + '=' +#ValueFieldPara + ' ORDER BY ' +#TextField+' ASC;') "
all variables are populated from c# back end.
is there any solution?

If you want to set the table, you need dynamic SQL. Here is one method:
declare #sql nvarchar(max);
declare #cnt int;
set #sql = '
SELECT #cnt = COUNT(*)
FROM #TableName
WHERE #TextFieldPara = #ValueFieldPara
');
set #sql = replace(#sql, '#TableName', #TableName);
set #sql = replace(#sql, '#TextFieldPara', #TextFieldPara);
set #sql = replace(#sql, '#ValueFieldPara', #ValueFieldPara);
exec sp_executesql(#sql, N'#cnt int output', #cnt=#cnt output);
if (#cnt > 0) . . .
begin
set #Message = #TextField + ' Already Exist...';
end
else
begin
set #Message = 'TRUE';
end;
I simplified the query because you don't need a select list or order by for determining the existing of values. I also used count(*) just because it is simpler to express. If you care about performance, there are better methods, such as a case with an exists in it.
Similarly, you should use quotename() for the identifiers in the query. You don't have that in your sample code, but it is a best practice.

Related

Loop through Query and Update field

I'm trying to loop through a fields defined in a query to an update statement.
I have the following SQL:
Declare #SQL varchar(max)
#SQL= 'Select [a],[b],[c],[d],[e]....[z]
From Table1;'
I want to be able to loop through all the fields [a]-[z] and update via the following statement:
Update Table 1
Set [a] = Case when [a] = 'Not at all' Then 0
when [a] = 'Very Much' Then 10 End
Field names are not actually [a]..[z]; I can't run the the update statement on the whole table, only a specific set of field names.
Struggling to write it programatically in SQL Server.
Declare #SQL varchar(max)
Declare #name varchar(100)
DECLARE #getid CURSOR
Set #getid = cursor for
SELECT name
FROM
sys.dm_exec_describe_first_result_set('Select [a],[b],[c],[d],[e]....[z]
From Table1', NULL, 0)
Open #getid
FETCH NEXT
FROM #getid INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'Update Table1
Set ' + #name + ' = Case when ' + #name +'= ''Very Much'' Then ''10''
when ' + #name + ' = ''Not at all'' Then ''0''
Else ' + #name + ' End'
Exec(#SQL)
FETCH NEXT
FROM #getid INTO #name
END
CLOSE #getid
DEALLOCATE #getid
Basically dm_exec_describe_first_result_set is grabbing the fieldnames and outputting it as a recordset. Then we are just passing the the each of the records to #name and use it form our update statement and then executing it for each record passed.
Hope this helps someone else! Curious to see if there is a better way.
I think if you want to make it a little more generic I would do something like the following code. This will allow you to not have to write the specific query for every table you want to do this to and you could potentially filter out columns you do not want in the future.
To be clear, I borrowed the SQL to do the actual UPDATE from #Dale-K post and just made it pretty.
DECLARE #strSQL NVARCHAR(1000)
DECLARE #strTable NVARCHAR(100)
DECLARE #strColName VARCHAR(100)
SET #strTable = N'Table1'
CREATE TABLE #COLUMNS(ColName varchar(100))
SET #strSQL = ' select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = #TableName and DATA_TYPE in (''nvarchar'', ''varchar'')'
INSERT INTO #COLUMNS
EXEC sp_executeSQL #strSQL, N'#TableName nvarchar(100)', #TableName = #strTable
DECLARE csrColumns CURSOR LOCAL FORWARD_ONLY FOR
SELECT ColName FROM #COLUMNS
OPEN csrColumns
FETCH csrColumns INTO #strColName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #strSQL = N'UPDATE ' + #strTable + '
SET ' + #strColName + ' = CASE WHEN ' + #strColName +'= ''Very Much'' THEN ''10''
WHEN ' + #strColName + ' = ''Not at all'' THEN ''0''
ELSE ' + #strColName + ' END'
exec sp_ExecuteSQL #strSQL
FETCH csrColumns INTO #strColName
END
CLOSE csrColumns
DEALLOCATE csrColumns

Why Is it giving me "Must declare the Scalar variable "#jobnumber" "

DECLARE #sql VARCHAR(8000)
,#jobNumber VARCHAR(25)
,#DBName VARCHAR(30)
SET #jobNumber = '417133'
DROP TABLE #Actual
CREATE TABLE #Actual (
jobnumber INT
,firstNameCounts VARCHAR(25)
,lastNameCounts VARCHAR(25)
,address1Counts VARCHAR(25)
,address2Counts VARCHAR(25)
,cityCounts VARCHAR(25)
,stateCounts VARCHAR(25)
,zipCounts VARCHAR(25)
,inHomeDateCounts VARCHAR(25)
)
SET #sql = 'INSERT INTO #actual (jobnumber,firstNameCounts,lastNameCounts ,
address1Counts, address2Counts, cityCounts, stateCounts, zipCounts,
inHomeDateCounts) '
SET #sql = #sql + ' Select s.jobnumber, count(s.firstName) AS
[firstNameCounts], Count (s.lastName) AS [lastNameCounts], Count (s.Address1)
As [address1Counts], Count (s.address2)-Count (address2) AS '
SET #sql = #sql + ' [address2Counts], Count (s.City) AS [cityCounts], Count
(s.State) AS [stateCounts], Count (s.Zip) AS [zipCounts], Count
(jb.inHomeDate) AS [inHomeDateCounts] '
SET #sql = #sql + ' From [s-portaldb1].[tdis_417133) + ].[dbo].
[tblStandardFinal] s '
SET #sql = #sql + ' INNER JOIN [s-printstream].[tdSchedule2].[dbo].
[tblJobTicketActions] jb '
SET #sql = #sql + ' ON jb.psFlagJobNumber = s.jobNumber '
*SET #sql = #sql + ' where jobNumber = #jobNumber '* Getting error here
SET #sql = #sql + ' group by jobNumber '
PRINT #SQL
EXEC (#sql)
SELECT *
FROM #Actual
I am getting this
Error: Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#jobNumber". I have declared the value and not sure what the reason could be.
any help would be appreciated.
Because you are executing SQL with exec() and have not provided a declaration for that variable inside the executed sql. #sql will be executed in its own context, and will not be able to access the variable of the same name that you have declared outside of the executed sql.
You could instead use sp_executesql which allows for parameter declaration and passing of parameters.
declare #sql nvarchar(max); /* nvarchar() instead of varchar() */
...
exec sp_executesql #sql, N'#JobNumber Varchar(25)', #JobNumber;
dynamic sql reference:
The curse and blessings of dynamic SQL - Erland Sommarskog
sp_executesql
You are running dynamic SQL - it runs in its own context and doesn't have access to the declared variables you have.
Either construct the dynamic SQL with the value being passed in (in the SQL string you later execute), or figure out how to do this without dynamic SQL (I don't see a reason for building the string and the EXECuting it).
All that string concatenation seems completely superfluous.
So instead of this:
SET #sql = 'INSERT INTO #actual (jobnumber,firstNameCounts,lastNameCounts ,
address1Counts, address2Counts, cityCounts, stateCounts, zipCounts,
inHomeDateCounts) '
SET #sql = #sql + ' Select s.jobnumber, count(s.firstName) AS
[firstNameCounts], Count (s.lastName) AS [lastNameCounts], Count (s.Address1)
As [address1Counts], Count (s.address2)-Count (address2) AS '
SET #sql = #sql + ' [address2Counts], Count (s.City) AS [cityCounts], Count
(s.State) AS [stateCounts], Count (s.Zip) AS [zipCounts], Count
(jb.inHomeDate) AS [inHomeDateCounts] '
SET #sql = #sql + ' From [s-portaldb1].[tdis_417133) + ].[dbo].
[tblStandardFinal] s '
SET #sql = #sql + ' INNER JOIN [s-printstream].[tdSchedule2].[dbo].
[tblJobTicketActions] jb '
SET #sql = #sql + ' ON jb.psFlagJobNumber = s.jobNumber '
SET #sql = #sql + ' where jobNumber = #jobNumber '
SET #sql = #sql + ' group by jobNumber '
PRINT #SQL
EXEC (#sql)
You should just have:
INSERT INTO #actual (jobnumber,firstNameCounts,lastNameCounts ,
address1Counts, address2Counts, cityCounts, stateCounts, zipCounts,
inHomeDateCounts)
Select s.jobnumber, count(s.firstName) AS
[firstNameCounts], Count (s.lastName) AS [lastNameCounts], Count (s.Address1)
As [address1Counts], Count (s.address2)-Count (address2) AS
[address2Counts], Count (s.City) AS [cityCounts], Count
(s.State) AS [stateCounts], Count (s.Zip) AS [zipCounts], Count
(jb.inHomeDate) AS [inHomeDateCounts]
From [s-portaldb1].[tdis_417133) + ].[dbo].
[tblStandardFinal] s
INNER JOIN [s-printstream].[tdSchedule2].[dbo].[tblJobTicketActions] jb
ON jb.psFlagJobNumber = s.jobNumber
where jobNumber = #jobNumber
group by jobNumber

Return Row Count Using Dynamic SQL

I'm trying to run the following Dynamic SQL statement:
#Tbl, #Fld, and #LookupValue have all been set according to Table to search, Field (Or Column) to search and column value to compare.
DECLARE #Sql AS VARCHAR(500)
SET #Sql = 'SELECT COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
I want to store the result into a variable so I can check to see if there are any returned rows. This statement is in the middle of a WHILE construct that is checking several tables and fields.
If records are found, then I want to display:
SET #Sql = 'SELECT ' + #Fld +
' FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
Yes, you can store it in a typed variable and use sp_executesql like
DECLARE #Sql AS NVARCHAR(500);
DECLARE #cnt INT;
SET #Sql = 'SELECT #cnt = COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + '''';
EXEC sp_executesql #Sql, N'#cnt INT OUTPUT', #cnt OUTPUT;
SELECT #cnt;
you can create a temporary table and store the count value.
if object_id('tempdb.#mycount') is null
create table #mycount ( countVal int);
DECLARE #Sql AS VARCHAR(500)
SET #Sql = 'INSERT INTO #mycount
SELECT COUNT(*)
FROM ' + #Tbl +
' WITH (NOLOCK)
WHERE ' + #Fld + ' = ''' + #LookupValue + ''''
EXEC(#Sql)
select countVal from #mycount
-- once the temp table usage is done, you can delete it
drop table #mycount

sql with single quotes for parameter in where clause

I have below sql where I am trying to pass name parameter to sql, how can i append, I am getting syntax errors..
I have to #name in place of steeve
if #name not null BEGIN
set #sql = #sql + ' AND name=''steeve''';
END
if #name is not null then
BEGIN
set #sql = #sql + ' AND name=''' + #name + '''';
END

Execute a Stored Procedure in a SELECT statement

For an instance I a select statement and it is returning 1000 rows. I need to execute a particular stored procedure for every row the the select statement is returning.
have you got any idea how can I do that?
Construct the EXECUTE statements in your select like this:
SELECT 'EXEC sp_whatever ' + parameter stuff
FROM your_table
Then run the results! Alternatively, paste your results into a spreadsheet package, and use string concatenation to construct the EXEC statements - just create a formula and paste it down the 1,000 rows. I personally prefer the first approach.
To clarify the "parameter stuff", take the example of a stored procedure that takes two int parameters that you want to take from columns you your_table. You'd then have something like this:
SELECT 'EXEC sp_whatever ' + CAST(field1 AS varchar) + ', ' + CAST(field2 AS varchar)
FROM your_table
Not the need to be careful with string fields here - you run the risk of inadvertently exposing yourself to your own SQL injection attack, as with any SQL string concatenation.
I am reading your "for an instance" as "this is a one-off task". If this is a task that needs automating, then one of the other answers may be the right approach.
You can do it like this:
declare #execstatementsbatch nvarchar(max)
select #execstatementsbatch = ''
SELECT #execstatementsbatch = #execstatementsbatch + 'EXEC UpdateQty ' + ItemCode + ', ' + QtyBO + '; '
FROM ITEMSPO
INNER JOIN .....
<some conditions>
exec(#execstatementsbatch)
Disclaimer: I'm not sure if I understand your question correctly.
Assuming you are on SQL Server 2005 upwards, you could create a table-valued user defined function and use the OUTER APPLY operator in your query.
Most RDBMS will let you select rows from stored procedure result sets. Just put your stored procedures in the FROM clause, as you would for common table expressions. For instance:
SELECT sp.ColumnInResultSet, t.BaseTableColumnName
FROM sp_whatever ( Args) sp INNER JOIN BaseTable t ON t.ID = sp.ID;
CREATE PROCEDURE dbo.usp_userwise_columns_value
(
#userid BIGINT
)
AS
BEGIN
DECLARE #maincmd NVARCHAR(max);
DECLARE #columnlist NVARCHAR(max);
DECLARE #columnname VARCHAR(150);
DECLARE #nickname VARCHAR(50);
SET #maincmd = '';
SET #columnname = '';
SET #columnlist = '';
SET #nickname = '';
DECLARE CUR_COLUMNLIST CURSOR FAST_FORWARD
FOR
SELECT columnname , nickname
FROM dbo.v_userwise_columns
WHERE userid = #userid
OPEN CUR_COLUMNLIST
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
FETCH NEXT FROM CUR_COLUMNLIST
INTO #columnname, #nickname
WHILE ##FETCH_STATUS = 0
BEGIN
SET #columnlist = #columnlist + #columnname + ','
FETCH NEXT FROM CUR_COLUMNLIST
INTO #columnname, #nickname
END
CLOSE CUR_COLUMNLIST
DEALLOCATE CUR_COLUMNLIST
IF NOT EXISTS (SELECT * FROM sys.views WHERE name = 'v_userwise_columns_value')
BEGIN
SET #maincmd = 'CREATE VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), #userid) + ') as userid , '
+ CHAR(39) + #nickname + CHAR(39) + ' as nickname, '
+ #columnlist + ' compcode FROM dbo.SJOTran '
END
ELSE
BEGIN
SET #maincmd = 'ALTER VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), #userid) + ') as userid , '
+ CHAR(39) + #nickname + CHAR(39) + ' as nickname, '
+ #columnlist + ' compcode FROM dbo.SJOTran '
END
--PRINT #maincmd
EXECUTE sp_executesql #maincmd
END
-----------------------------------------------
SELECT * FROM dbo.v_userwise_columns_value