T-SQL if exists - tsql

I am summer intern new to T-SQL and I have to run an sql select statement on various databases. What I would like to do is use 'if exists' to keep an error from occuring because some of the databases on the list to have this statement executed on no longer exist. However, I cannot figure out how to apply it to my statement. Any help would be greatly appreciated. Below is the statment me and another intern wrote:
select distinct mg.MatterName, mg.ClientNumber, mg.MatterNumber,grp.groupName as SecurityGroup
from (select distinct mat.matterName, mat.clientNumber, mat.matterNumber, usr.GroupID
from <db_name>.dbo.matter mat
inner join <db_name>.dbo.usrAccount usr
on usr.NTlogin=mat.matterCreateBy) as mg
inner join <db_name>.dbo.usrGroup grp
on mg.groupID=grp.groupID
order by matterName
the < db_name> is where the passed in parameter that is the name of the database, would go.

You could use sp_MSforeachdb to enumerate all of the databases on the instance.
This would be similar to:
exec sp_MSforeachdb 'select distinct mg.MatterName, mg.ClientNumber, mg.MatterNumber,grp.groupName as SecurityGroup from (select distinct mat.matterName, mat.clientNumber, mat.matterNumber, usr.GroupID from ?.dbo.matter mat inner join ?.dbo.usrAccount usr on usr.NTlogin=mat.matterCreateBy) as mg inner join ?.dbo.usrGroup grp on mg.groupID=grp.groupID order by matterName'
Alternatively, you could use dynamic sql to manufacture a script:
select 'use ' + name + ';' + char(13) + 'select distinct mg.MatterName, mg.ClientNumber, mg.MatterNumber,grp.groupName as SecurityGroup' +CHAR(13) + 'from (select distinct mat.matterName, mat.clientNumber, mat.matterNumber, usr.GroupID' + char(13) + 'from dbo.matter mat' + char(13) + 'inner join dbo.usrAccount usr on usr.NTlogin=mat.matterCreateBy) as mg' + char(13) + 'inner join dbo.usrGroup grp on mg.groupID=grp.groupID' + CHAR(13) + 'order by matterName;'
from master.sys.databases where database_id>4
If you redirect your output to "Results to Text" in SSMS then run the script, you will see a script written that you can then put into a query editor to execute.

I got it to work. I think this is a bit hackey but what I did was catch the exception thrown and just change a label on the page to reflect that the database doesnt exist.
DataAccess dal = new DataAccess();
dal.SelectedConnectionString = "WebServer08";
String exNetName = Request.QueryString["name"];
if (exNetName != null && !exNetName.Equals(""))
{
try
{
gvMatters.DataSource = dal.GetMatters(exNetName);
gvMatters.DataBind();
}
catch (Exception ex)
{
noDB.Text = "This database doesn't exist.";
gvMatters.Visible = false;
}
}
And i just left the SQL statement the way it was rather than try to screw around with it

Related

T-SQL stored procedure to get data from any table on the server for CSV export (SQL Server 2016)

Answered / Solved.
Long story short, I need a stored procedure that would get the data from a few different views and put it into a .CSV file. Easy enough, but me being me, I decided to write something that could get the data from any table one could potentially desire. I decided to go with 2 procedures in the end:
Loop through a table with all the parameters (catalog, schema, table name, export path/file name etc. etc.) and feed it to 2nd stored procedure (in theory it should make it easier to manage in future, if/when different data needs to be exported). This one is fairly straightforward and doesn't cause any issues.
Pick up the column names (which was surprisingly easy - below in case it helps anyone)
select #SQL = 'insert into Temp_Export_Headers ' +
'select COLUMN_NAME ' +
'from [' + #loc_Source_Database + '].information_schema.columns ' +
'where table_name = ''' + #loc_Source_Table + ''''
and
select #Headers = coalesce(#Headers + ',', '') + convert(varchar, Column_Name)
from Temp_Export_Headers
After that, I want to dump all the data from "actual" table into temp one, which in itself is easy enough, but that's where things start to go downhill for me.
select #SQL =
'drop table if exists TempData ' +
'select * ' +
'into TempData ' +
'from [' + #loc_Source_Database + '].' + #loc_Source_Schema + '.' + #loc_Source_Table + ' with (nolock) '
Select * is just temporary, will probably replace it with a variable later on, for now it can live in this state on dev.
Now I want to loop through TempData and insert things I want (everything at the moment, will add some finesse and where clauses in near future) and put it into yet another temp table that holds all the stuff for actual CSV export.
Is there any way to add a self incrementing column to my TempData without having to look for and get rid of the original PK / Identity? (Different tables will have different values / names for those, making it a bit of a nightmare for someone with my knowledge / experience to loop through in a sensible manner, so I'd just like a simple column starting with 1 and ending with whatever last row number is)
#ShubhamPandey 's answer was exactly what I was after, code below is a product of my tired mind on the verge of madness (It does, however, work)
select #SQL =
'alter table TempData ' +
'add Uni_Count int'
select #SQL2 =
'declare #UniCount int ' +
'select #UniCount = 0 ' +
'update tempdata with (rowlock) ' +
'set #UniCount = Uni_Count = #UniCount + 1'
Both versions execute quicker than select * into without any other manipulation. Something I cannot yet comprehend.
Is there a better / more sensible way of doing this? (My reasoning with the loop - there will potentially be a lot of data for some of the tables / views, with most of them executed daily, plan was to export everything on Sat/Sun when system isn't that busy, and have daily "updates" going from last highest unique id to current.)
Looping was a horrible idea. To illustrate just how bad it was:
Looping through 10k rows meant execution time of 1m 21s.
Not looping through 500k rows resulted in execution time of 56s.
Since you are doing a table creation while insertion, you can always go forward with a statement like:
select #SQL =
'drop table if exists TempData ' +
'select ROW_NUMBER() OVER (<some column name>) AS [Id], * ' +
'into TempData ' +
'from [' + #loc_Source_Database + '].' + #loc_Source_Schema + '.' + #loc_Source_Table + ' with (nolock) '
This would create an auto-incrementing index for you in the TempData table

ADO.NET working with SQL and database

I'm getting an exception error saying missing operators can anyone help
string sql = "Select SalesPerson.Name, Item.Description, Orders.Quantity, Orders.OrderDate"
+ "From([Orders]"
+ "Inner Join[SalesPerson] On Orders.SalesPersonID=SalesPerson.SalesPersonID)"
+ "Inner Join[Item] On Orders.ItemNumber=Item.ItemNumber"
+ "Where Orders.CustomerID=#customer Order by Orders.OrderDate DESC";
You need to add some spaces at the end of each of your lines of SQL!
string sql = "SELECT SalesPerson.Name, Item.Description, Orders.Quantity, Orders.OrderDate "
+ "FROM [Orders] "
+ "INNER JOIN [SalesPerson] ON Orders.SalesPersonID = SalesPerson.SalesPersonID "
+ "INNER JOIN [Item] ON Orders.ItemNumber = Item.ItemNumber "
+ "WHERE Orders.CustomerID = #customer "
+ "ORDER BY Orders.OrderDate DESC";
Otherwise, your SQL ends up being
Select ..... Orders.OrderDateFROM([Orders]Inner Join[SalesPerson] .....
and so on - and that's just not valid SQL.
I also removed some unnecessary parenthesis around the JOIN operators - those are only needed for MS Access, but since you're saying you're using ADO.NET, I assume this is not for MS Access and therefore, those parenthesis are not needed

How to execute raw query in JPA?

I'm trying to execute a raw query like this:
em.createNativeQuery(
"WITH RECURSIVE recursetree(id, parent_id) AS (\n" +
"SELECT id, parent_g_id FROM group WHERE parent_g_id = 2\n" +
"UNION\n" +
" SELECT t.id, t.parent_g_id\n" +
" FROM group t\n" +
" JOIN recursetree rt ON rt.id = t.parent_g_id\n" +
" )\n" +
"SELECT * FROM recursetree;").getResultList();
On the Postgres side (via PGAdmin) it works fine, but from Java it get the following error:
java.lang.IllegalArgumentException: argument type mismatch
What do I do wrong? How to execute a really raw query on Postgres from a Java EE environment?

query throwing error in web report writer

I have a query/view that is created to be used in a report. When I run in the SMS and in SSRS it run fine. But when I connect the view to the tool that generates our reports it throws the following error. Incorrect syntax near '.8'. When I contact the support for this product they say it has to do with how we calculate the 8thgradyear . I have placed the code below. Any suggestions.
SELECT
dbo.studemo.suniq,
dbo.studemo.ident,
dbo.studemo.lastname,
dbo.studemo.firstname,
dbo.studemo.emailaddr AS stuemail,
dbo.studemo.birthdate,
dbo.track.schoolc,
dbo.school.schname,
dbo.stustat.graden,
dbo.stustat.edate,
dbo.zstustat.descript AS status,
RTRIM(dbo.facdemo.lastname) + ' ' + dbo.facdemo.firstname AS advisor,
dbo.track.schyear,
SUM(8) - dbo.stustat.graden + dbo.track.schyear AS [8thgradyear],
sf.Email, LOWER(sf.Username) AS [user],
LOWER(RIGHT(SUM(8) - dbo.stustat.graden + dbo.track.schyear, 2) + LEFT(dbo.studemo.firstname, 1) + REPLACE(REPLACE(REPLACE(dbo.studemo.lastname, '-', ''), ' ', ''), '''', '') + RIGHT(dbo.studemo.ident, 3)) AS newuser,
CONVERT(varchar(8), dbo.studemo.birthdate,1) AS password,
'STUDENTS' + '/' + (CASE WHEN track.schoolc IN ('19', '43', '17', '23') THEN 'Middle' ELSE 'Elementary' END) + '/' + dbo.school.schname AS neworg,
sf.OU, sf.LastLoginTime
FROM dbo.studemo INNER JOIN
dbo.stustat ON dbo.studemo.suniq = dbo.stustat.suniq INNER JOIN
dbo.track ON dbo.stustat.trkuniq = dbo.track.trkuniq INNER JOIN
dbo.zstustat ON dbo.stustat.stustatc = dbo.zstustat.stustatc INNER JOIN
dbo.facdemo ON dbo.stustat.funiq = dbo.facdemo.funiq LEFT OUTER JOIN
dbo.vw_google_OU AS sf ON sf.Firstname = dbo.studemo.firstname AND sf.Lastname = dbo.studemo.lastname INNER JOIN
dbo.school ON dbo.school.schoolc = dbo.track.schoolc
WHERE (dbo.stustat.stustatc IN
(SELECT stustatc
FROM dbo.zstustat AS zstustat_1
WHERE (snstatus IN ('A', 'M', 'P')))) AND (dbo.stustat.xdate IS NULL OR
dbo.stustat.xdate < dbo.stustat.edate) AND (dbo.track.schoolc NOT IN ('P34', 'P24', '802', '801'))
GROUP BY dbo.studemo.suniq, dbo.studemo.ident, dbo.studemo.lastname, dbo.studemo.firstname, dbo.studemo.birthdate, RIGHT(dbo.studemo.ident, 3), dbo.track.schoolc,
dbo.stustat.graden, dbo.zstustat.descript, RTRIM(dbo.facdemo.lastname) + ' ' + dbo.facdemo.firstname, dbo.stustat.edate, dbo.studemo.gradyear, dbo.track.schyear,
sf.Email, CONVERT(varchar(8), dbo.studemo.birthdate, 1), sf.Username, dbo.school.schname, sf.OU, dbo.studemo.emailaddr, sf.LastLoginTime
SUM function was introduced in SQL Server 2008 and your tool must be using and older version of SQL Server.

UPDATE table via join in SQL

I am trying to normalize my tables to make the db more efficient.
To do this I have removed several columns from a table that I was updating several columns on.
Here is the original query when all the columns were in the table:
UPDATE myActDataBaselDataTable
set [Correct Arrears 2]=(case when [Maturity Date]='' then 0 else datediff(d,convert(datetime,#DataDate, 102),convert(datetime,[Maturity Date],102)) end)
from myActDataBaselDataTable
Now I have removed [Maturity Date] from the table myActDataBaselDataTable and it's necessary to retrieve that column from the base reference table ACTData, where it is called Mat.
In my table myActDataBaselDataTable the Account number field is a concatenation of 3 fields in ACTData, thus
myActDataBaselDataTable.[Account No]=ac.[Unit] + ' ' + ac.[ACNo] + ' ' + ac.[Suffix]
(where ac is the alias for ACTData)
So, having looked at the answers given elsewhere on SO (such as 1604091: update-a-table-using-join-in-sql-server), I tried to modify this particular update statement as below, but I cannot get it right:
UPDATE myActDataBaselDataTable
set dt.[Correct Arrears 2]=(
case when ac.[Mat]=''
then 0
else datediff(d,convert(datetime,'2014-04-30', 102),convert(datetime,ac.[Mat],102))
end)
from ACTData ac
inner join myActDataBaselDataTable dt
ON dt.[Account No]=ac.[Unit] + ' ' + ac.[ACNo] + ' ' + ac.[Suffix]
I either get an Incorrect syntax near 'From' error, or The multi-part identifier "dt.Correct Arrears 2" could not be bound.
I'd be grateful for any guidance on how to get this right, or suugestiopns about how to do it better.
thanks
EDIT:
BTW, when I run the below as a SELECT it returns data with no errors:
select case when [ac].[Mat]=''
then 0
else datediff(d,convert(datetime,'2014-04-30', 102),convert(datetime,[ac].[Mat],102))
end
from ACTData ac
inner join myActDataBaselDataTable dt
ON dt.[Account No]=ac.[Unit] + ' ' + ac.[ACNo] + ' ' + ac.[Suffix]
In a join update, update the alias
update dt
What is confusing is that in later versions of SQL you don't need to use the alias in the update line