This is in SQL server 2012. I'm on Sever Management studio.
I have multiple servers that have multiple databases that I need to feed it a varying list of Database names to pull back a sum of a size field. At the moment #sql2 updates the BR_ProductionSize to the actual select statement instead of the answer to that statement.
DECLARE #TempCaseArtifactID NVARCHAR(60)
DECLARE #sql2 NVARCHAR(200)
DECLARE #answer NVARCHAR(200)
set #TempCaseArtifactID = (select '[EDDS'+BR_CaseArtifactid+'].[EDDSDBO].[File]' from #BRFindSizes where UpdateCompleted = '2')
set #sql2 = '(select SUM(size) FROM '+#TempCaseArtifactID + ' where TYPE = 3 and InRepository = 1)'
IF (select BR_sqlServerID from #BRFindSizes where UpdateCompleted = '2') = 1015083
Begin
update #BRFindSizes
set BR_ProductionSize = #sql2
where UpdateCompleted = '2'
end
This answer is untested and might have some syntax errors, but it represents the gist of what you want to do.
You have this (actually, I put in the SumOfSizes alias):
set #sql2 = '(select SUM(size) SumOfSizes
FROM '+#TempCaseArtifactID + '
where TYPE = 3 and InRepository = 1)'
Which is a string. To the the value, you have to execute that query and put the result into a variable. This is the general idea.
set #valueIWant = SumOfSizes from
sp_executesql #SQLString #sql2
Then you use the #valueIWant variable in your update query.
For the correct syntax, read this.
You have to Execute the dynamic statement that you have created, to use the value generated.
What you should do is
DECLARE #sql2 VARCHAR(50) = EXEC '(select CONVERT(VARCHAR, SUM(size)) FROM '
+ #TempCaseArtifactID
+ ' where TYPE = 3 and InRepository = 1)'
And then
IF (select BR_sqlServerID from #BRFindSizes where UpdateCompleted = '2') = 1015083
BEGIN
UPDATE #BRFindSizes
SET BR_ProductionSize = #sql2
WHERE UpdateCompleted = '2'
END
The same thing goes for #TempCaseArtifactID.
Related
I'm running a Restore Verify Only loop through a table, but I need it to UPDATE a field in that table if it's successful. Here is my code:
DECLARE #Path NVARCHAR(max)
DECLARE #DatabaseName NVARCHAR(100)
DECLARE #NSql NVARCHAR(1000)
DECLARE #Update NVARCHAR(200)
DECLARE #DB_Text NVARCHAR(50)= 'Backup has been confirmed for'
BEGIN
DECLARE
#DatabaseId INT = 1,
#NumberOfDBs INT
SELECT #NumberOfDBs= COUNT(*) FROM dbo.RestoreVerifyDatabases
WHILE #DatabaseId<= #NumberOfDBs
BEGIN
SELECT * FROM dbo.RestoreVerifyDatabases WHERE DatabaseId= #DatabaseId
SET #DatabaseId = #DatabaseId + 1
END
SET #Path = (SELECT LastBackupFileName FROM RestoreVerifyDatabases WHERE DatabaseId =
#DatabaseId)
SET #DatabaseName = (SELECT DatabaseName FROM RestoreVerifyDatabases WHERE DatabaseId =
#DatabaseId)
SET #NSql = N'SELECT LastBackupFileName
FROM RestoreVerifyDatabases
WHERE DatabaseName = #DatabaseName
AND DatabaseId = #DatabaseId'
EXEC sp_executesql #NSql
IF #DatabaseId IS NULL
BEGIN
RAISERROR(N'Verify failed. Backup information for database N''#DatabaseName'' not
found.', 16, 1)
END
RESTORE VERIFYONLY
FROM #Path
WITH FILE = #DatabaseId, checksum
SET #Update= N'UPDATE RestoreVerifyDatabases
SET Confirmed = #DB_Text + #DatabaseName
WHERE DatabaseID = #DatabaseId'
EXEC sp_executesql #Update
END
The looping and calling of Restore Verify Only works fine but the UPDATE is not getting called. Please help.
There's a few things wrong with your code as far as I can see. As my comment indicated, you run a loop over the #databaseID, and then immediately increase the id with 1 within the loop.
This means your #databaseId simply will increase until it reaches the maximum value of the id, and then exits the loop. The rest of your code will then execute once (only for that ID).
That happens here in your code:
SELECT #NumberOfDBs= COUNT(*) FROM dbo.RestoreVerifyDatabases
WHILE #DatabaseId<= #NumberOfDBs
BEGIN
SELECT * FROM dbo.RestoreVerifyDatabases WHERE DatabaseId= #DatabaseId
SET #DatabaseId = #DatabaseId + 1
END
-- Bunch of other code
So #databaseID goes from 1 to 50 (just a random number) within that loop, then exists with a value of 50. None of the underlying code ever gets to see any value other than 50.
To fix that, the code should look like this:
SELECT #NumberOfDBs= COUNT(*) FROM dbo.RestoreVerifyDatabases
WHILE #DatabaseId<= #NumberOfDBs
BEGIN
SELECT * FROM dbo.RestoreVerifyDatabases WHERE DatabaseId= #DatabaseId
-- Bunch of other code
SET #DatabaseId = #DatabaseId + 1
END
This would ensure the "bunch of other code" processes #databaseid = 1, then processes #databaseid = 2, etc. until #databaseid = 50.
You can also remove this line:
SELECT * FROM dbo.RestoreVerifyDatabases WHERE DatabaseId= #DatabaseId
I suspect you have it for debugging purposes, but it doesn't really do anything.
These lines can be simplified:
SET #Path = (SELECT LastBackupFileName FROM RestoreVerifyDatabases WHERE DatabaseId =
#DatabaseId)
SET #DatabaseName = (SELECT DatabaseName FROM RestoreVerifyDatabases WHERE DatabaseId =
#DatabaseId)
as:
SELECT #Path = LastBackupFileName, #DatabaseName = DatabaseName FROM RestoreVerifyDatabases WHERE DatabaseId = #DatabaseId
You also have a RAISEERROR. I suspect that is because you do a count(*), rather than selecting actually existing #databaseids. This works in an ideal scenario, where databases never get deleted. In the reasl world, though, you'd go from databaseid 1 to 5, because 2, 3, and 4 were removed. Your count will still be 50 databases, but you'd miss all databases with ids above the count due to these gaps. You'd be trying to process the databaseid that no longer exists, and miss the ones with an id > 50.
You could instead write your loop to do something like the following:
SELECT #DatabaseID = MIN(DatabaseID) FROM dbo.RestoreVerifyDatabases
WHILE #datbaseID IS NOT NULL
BEGIN
-- Do stuff
SELECT #DatabaseID = MIN(DatabaseID) FROM dbo.RestoreVerifyDatabases WHERE databaseID > #databaseID
END
Finally, your dynamic code isn't working. You are adding literal text rather than the value of the parameters. If I print the value of #Update at the end, it shows as:
UPDATE RestoreVerifyDatabases
SET Confirmed = #DB_Text + #DatabaseName
WHERE DatabaseID = #DatabaseId
Your code should be something like:
SET #Update= CONCAT('UPDATE RestoreVerifyDatabases SET Confirmed = ''', #DB_Text, ' ', #DatabaseName, ''' WHERE DatabaseID = ', #DatabaseId)
Which outputs:
UPDATE RestoreVerifyDatabases SET Confirmed = 'Backup has been confirmed for Last' WHERE DatabaseID = 2
I am working with MS SQL. I wrote a simple code which goes through columns in my table and find the columns with more than 30% zero value. I will save name of column with more than 30% zero in #array.#count just has number of columns and #column has name of all columns.
DECLARE #array varchar(MAX)
DECLARE #sql varchar(MAX),
#column as varchar(MAX)
SELECT #count = (SELECT COUNT(*) FROM sys.columns WHERE object_id =
OBJECT_ID('UVE305_TREND_2.dbo.LOGTNK'))
WHILE #counT>0
BEGIN
SET #column = (SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('UVE305_TREND_2.dbo.LOGTNK') AND column_id = #count)
SELECT #column
SET #array = (SELECT COUNT(#column) FROM UVE305_TREND_2.dbo.LOGTNK WHERE
#column = 0 )
select #array
SET #count= #count- 1
END;
IF #r_count >= CAST(#array AS INT)
SET #list= #column+','+#list;
when I tried to run my query I got following error:
Conversion failed when converting the varchar(max) value 'TNK_99' to
data type int.
'TNK_99' is my column name.
any help will be appreciated.
This expression:
WHERE #column = 0
Is being converted to:
WHERE 'TNK_99' = 0
That is, it is comparing a string (which happens to be a column name) to a number. By the rules of SQL the values are converted to numbers -- and you get a conversion error.
There is no simple way to solve this. The solution involves dynamic SQL, which is rather more complex than your code.
EDIT:
The code looks like:
DECLARE #sql NVARCHAR(MAX);
WHILE #count > 0
BEGIN
SET #column = (SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('UVE305_TREND_2.dbo.LOGTNK') AND column_id = #count);
SET #SQL = 'SELECT #array = COUNT(*) FROM UVE305_TREND_2.dbo.LOGTNK WHERE ' + QUOTENAME(#column) + ' = 0 )'
EXEC sp_executesql #SQL, N'#array int output', #array=#array output;
SELECT #column, #array
SET #count= #count- 1
END;
As with the original code, this assumes that all columns are numeric. This code is a little vague on what "zero value" means. Perhaps you intend:
SET #SQL = 'SELECT #array = COUNT(*) FROM UVE305_TREND_2.dbo.LOGTNK WHERE ' + QUOTENAME(#column) + ' = ''0'' )'
I have a variable which holds the database that I am working on. How can I add this variable in a static query?
This is what I want to achieve:
if exists(select * from #DestinationDB.[RaPa] where tid = #dyid)
begin
RAISERROR('Rapa exist',16,1)
end
I'm not sure if you meant without Dynamic SQL... but here is how you can accomplish this with dynamic SQL
declare #DestinationDB varchar(64)
declare #dyid int
declare #sql varchar(max)
set #DestinationDB = 'SomeDB'
set #dyid = 14
set #sql =
'if exists(select * from ' + quotename(#DestinationDB) + '.[RaPa] where tid = ' + cast(#dyid as varchar(16)) + ')
begin
RAISERROR(''Rapa exist'',16,1)
end'
print #sql
--exec(#sql)
Just uncomment the exec part when you are satisfied with the command.
It seems like a simple enough event you just declare a variable you are passing to your stored procedure as column. I am needing to pass a column name to my stored procedure that will be used in my query. Is it possible to declare it so I can use it as a column name or is there some way I can convert say a string to column type?
where Line1AStatus = 1
I need to be able to pass to my stored procedure what that number is in Line Status. I have tried these methods so far. Thank you for your help.
where Line + #LineNum + AStatus = 1
where 'Line' + #LinNum + 'AStatus' = 1
not with standard SQL but you can with dynamic sql
DECLARE #SQL nvarchar(max)
SELECT #SQL = 'SELECT * FROM table where ''Line' + CAST(#LinNum AS NVARCHAR) + 'AStatus'' = 1'
exec sp_executeSQL #sql
Example of a while loop
DECLARE #SQL nvarchar(max), #LinNum int
SELECT #LinNum = 1
WHILE(#LinNum <= 5)
BEGIN
SELECT #SQL = 'SELECT * FROM table where ''Line' + CAST(#LinNum AS NVARCHAR) + 'AStatus'' = 1'
exec sp_executeSQL #sql
SELECT #LinNum = #LinNum + 1
END
This query is to prove a concept that I will eventually use to locate all columns with a specific value and then create a name/value pair for export to JSON. But I'm stuck.
I query the list of all columns from the sql table. I would then like to go through the columns in Table1 row by row and update the values using the variable to construct the query. For example as it reads through the list if Col4 = "Old text" then I would like to set the value of Col 4 = "New Text"
DECLARE #c varCHAR(100)
DECLARE ReadData CURSOR
FOR SELECT cname FROM sys.syscolumns WHERE creator = 'dbserver' AND tname = 'Table1'
DECLARE #RowCount INT
SET #RowCount = (SELECT COUNT(cname) FROM sys.syscolumns WHERE creator = 'dbserver' AND tname = 'Table1')
OPEN ReadData
DECLARE #I INT // iterator
SET #I = 1 // initialize
WHILE (#I <= #RowCount)
BEGIN
FETCH NEXT ReadData INTO #c
INSERT INTO serverdb.Table2 (cname)VALUES(#c)// this works inserting all 100 columns in the cname column of Table 2
UPDATE serverdb.Table1 SET #c = 'New text' WHERE #c = 'Old text'// this fails with a syntax error. #c is not being interpreted for the query. Note: If I hard code the #c var (for testing)to a known column name, the query works as well
SET #I = #I + 1
END;
Why won't the update statement recognize the variable? What am I missing?
When you use varibale as mentioned below it is considered as a character string.
UPDATE serverdb.Table1 SET #c = 'New text' WHERE #c = 'Old text'
You need to create a dynamic query. use the execute method to execute your dynamic query
declare #sql varchar(999)
SELECT #sql = 'UPDATE serverdb.Table1 SET '+ #c + '= ''New text'' WHERE '+ #c+ ' = ''Old text'' '
execute(#sql)
Hope this helps