Use Cases of sys.databases and master.dbo.sysdatabases - sql-server

I'm trying to learn mssql with Rocky Linux on RHEL 8, however I've found examples of people pulling database names using
SELECT name FROM master.dbo.sysdatabases
I don't understand how this command was created, I'm not finding anything that points to using master.dbo.
I used this to obtain the same results, in my mind this is more straight forward and makes more sense. Maybe I'm missing something crucial - but that's why I'm asking a question.
SELECT name FROM sys.databases
Maybe in my use-case it doesn't make a difference, but is there a preferred method between these options?
I feel like I'm pulling hairs, but I'm just curious.

master is the name of the primary database, it is where many DMVs and catalog views are sourced, though several of those are also accessible from other databases (and even when referenced from other schemas).
master.dbo.sysdatabases
^ Specifically, this is a 3-part name, in the form [database].[schema].[object]. But it references a backward compatibility view that is only still there to avoid breaking code written before SQL Server 2005. You can see plenty of warnings about this here:
sys.sysdatabases
Note that it works with both dbo.sysdatabases and sys.sysdatabases because the schema part of the name is essentially ignored.
Your instinct is right that the catalog view is the better way to query the list of databases, both because it isn't deprecated and because it includes a much more complete set of properties about a database:
SELECT * FROM sys.databases;
But you could also say:
SELECT * FROM mydatabase.sys.databases;
SELECT * FROM master.sys.databases;
But there are other catalog views where this is not true. For example, these will give very different, database-specific results:
SELECT * FROM mydatabase.sys.tables;
SELECT * FROM master.sys.tables;
Some other background:
System Catalog Views
Querying the SQL Server System Catalog FAQ
System Databases

Related

Azure Data Factory- Referencing Lookup activities in Queries

I'm following a tutorial on Azure Data Factory migration from Azure SQL to Blob through pipelines. While most of the concepts make sense, the 'Copy Data' query is a bit confusing. I have a background in writing Oracle SQL, but Azure SQL on ADF is pretty different and I'm struggling to find specific technical documentation, probably because it's not widely adopted yet.
Pipeline configuration shown below:
Query is posted below:
SELECT data_source_table.PersonID,data_source_table.Name,data_source_table.Age,
CT.SYS_CHANGE_VERSION, SYS_CHANGE_OPERATION
FROM data_source_table
RIGHT OUTER JOIN CHANGETABLE(CHANGES data_source_table,
#{activity('LookupLastChangeTrackingVersionActivity').output.firstRow.SYS_CHANGE_VERSION})
AS CT ON data_source_table.PersonID = CT.PersonID
WHERE CT.SYS_CHANGE_VERSION <=
#{activity('LookupCurrentChangeTrackingVersionActivity').output.firstRow.CurrentChangeTrackingVersion}
Output to the sink Blob as a result of the 'Copy Data' query:
2,name2,14,4,U
7,name7,51,3,I
8,name8,31,5,I
9,name9,38,6,I
Couple questions I had:
There's a lot of external referencing from other activities in the 'Copy Data' query like #{activity('...').output.firstRow.CurrentChangeTrackingVersion. Is there a way to know the appropriate syntax to referencing external activities? Can't find any good documentation the syntax, like what .firstRow is or what the changetable output looks like. I can't replicate this query in SSMS, which makes it a bit of a black box for me.
SYS_CHANGE_OPERATION appears in the SELECT with no table name prefix. Is this directly querying from the table in SourceDataset? (It points to data_source_table, which has table tracking enabled) My main confusion stems from how table tracking information is stored in the enabled tables. Is there a way to show all the table's tracked changes in SSMS? I see some documentation on what the return values, but it's hard for me to visualize it without seeing it on the table, so an output query of some return values would be nice.
LookupLastChangeTracking activity queries in all rows from a table (which when I checked, is just one row), but LookupCurrentChangeTracking activity uses a CHANGE_TRACKING function to pull the version of the data sink in table_store_ChangeTracking_version. Why does it use a function when the data sink's version is already recorded in table_store_ChangeTracking_version?
Sorry for the many questions, but I can't find any way to make this learning curve a bit less steep. Any guides or resources would be awesome!
There is an article to get the same thing done from the UI and it will help you understand it better .
https://learn.microsoft.com/en-us/azure/data-factory/tutorial-incremental-copy-change-tracking-feature-portal .
1 . These are the Lookup activity ,. very straight forward , please read about them here .
https://learn.microsoft.com/en-us/azure/data-factory/control-flow-lookup-activity
2.SYS_CHANGE_OPERATION is a column on data_source_table and so that should be fine . Regarding the details on the how the change tracking (CT) is stored , I am not sure if all the system table are exposed on Azure SQL , but we did had few table on the on-prem version of the SQL which could be queried if needed . But for this exercise I think that will be an over kill .

SQL Server Mgmt Studio shows "invalid column name" when listing columns?

I'm used to scripting in Python or Matlab, and my first couple hours with SQL have been infuriating. I would like to make a list of columns appear on the screen in any way, shape, or form; but when I use commands like
select *
from "2Second Log.dbo.TagTable.Columns"
I keep getting the error:
Invalid column name '[the first column in my table]'.
even though I never explicitly asked for [the first column in my table], it found it for me. How can you correctly identify the first column name, and then still claim it's invalid!? Babies will be strangled.
This db was generated by Allen Bradley's FactoryTalk software. What I would really like to do is produce an actual list of "TagName" strings...but I get the same error when I try that. If there were a way to actually double click the table and open it up and look at it (like in Matlab), that would be ideal.
Echoing juergen's suggestion in the comment above. It looks like you're running the query on the master database, not the 2Second Log database that actually has your table. (You can tell this by looking at the database in the dropdown in the top left of your screenshot). Two things you can do:
Change the dropdown in the top left to 2Second Log. This will target your query to a different database
Put your database name in brackets as suggested by juergen i.e. select * from [2Second Log].dbo.TagTable
As an side, if you're looking for a good SQL tutorial, I highly recommend the Mode SQL tutorial. It's a fantastic interactive platform to get your SQL feet wet.
always use brackets when names/field have spaces or dashes.
select * from [2Second Log].dbo.TagTable

Is one way of stating tables in a query more 'optimal' than another?

Edit: I'm aware that SELECT * is bad practice, but it's used here just to focus the example SQL on the table statement rather than the rest of the query. Mentally exchange it for some column names if you prefer.
Given a database server MyServer (which we are presently connected to in SSMS), with several databases MyDb1, MyDb2, MyDb3 etc and default schema dbo, are any of the following equivilant queries (they will all return exactly the same result set) more "optimal" than the others?
SELECT * FROM MyServer.MyDb1.dbo.MyTable
I was told that this method (explicitly providing the full database name including server name) treats MyServer as a linked server and causes the query to run slower. Is this true?
SELECT * FROM MyDb1.dbo.MyTable
The server name isn't required as we're already connected to it, but would this run 'faster' than the above?
USE MyDb1
GO
SELECT * FROM dbo.MyTable
State the database we're using initially. I can't imagine that this is any better than the previous for a single query, but would it be more optimal for subsequent queries on the same database (ie, if we had more SELECT statements in the same format below this)?
USE MyDb1
GO
SELECT * FROM MyTable
As above, but omitting the default schema. I don't think this makes any difference. Does it?
SQL Server will always look for the objects you sepcify within the current "Context" if you do not specify a fully qualified name.
Is one faster than the other, sure, the same as a file name on your hard drive of "This is a really long name for a file but at long as it is under 254 it is ok.txt" will take up more hard-drive (toc) space than "x.txt". Will you ever notice it, no!
As far as the "USE" keyword, this just sets the context for you, so you dont have to fully qualify object names. The "USE" keyword is NOT sql, you cannot use in in another application (like a vb/c# app) or within a stored procedure but it is like the "GO" keyword in that it tells SSMS to do something, change the context.

Finding all views that are using linked server

I am updating url for linked servers. Before make the changes, I would like to know all views that have reference to this linked servers. Is there any programmatic way (TSQL) to perform this task?
Thanks for your help.
I am using SQL Server 2005, 2008 and 2012. The database servers that referencing linked servers are mostly SQL Server 2005
While it may return false positives, and won't capture any cases where a four-part name is constructed using dynamic SQL, this is probably the simplest approach:
SELECT name FROM sys.views
WHERE LOWER(OBJECT_DEFINITION([object_id])) LIKE LOWER('%LinkedServerName%');
This will find the views:
SELECT t2.name, OBJECT_DEFINITION(t1.[object_id]) view_definition
FROM sys.views t1 join sys.servers t2 on
OBJECT_DEFINITION(t1.[object_id]) like '%['+ t2.name + '].%' ESCAPE '['
It can fail if a table, view, schema or database has same name as a linked server.
In case some views have eluded the first check you can add this line this part is not checking for the square brackets surrounding the linked server name. But be aware that this part is more likely to include
extra unwanted views
or OBJECT_DEFINITION(t1.[object_id]) like '% '+ t2.name + '.%'
EDIT: Changed sys.sysservers to sys.servers. Thanks Aaron Bertrand
If you need to find database objects (e.g. tables, columns, triggers) by name - have a look at the FREE Red-Gate tool called SQL Search which does this - it searches your entire database for any kind of string(s).
It's a great must-have tool for any DBA or database developer - did I already mention it's absolutely FREE to use for any kind of use??
Try This:
SELECT name, OBJECT_DEFINITION([object_id]) FROM sys.views
where OBJECT_DEFINITION([object_id]) like '%.%.dbo.%'

In SQL Server Management Studio, does this type of query run faster?

My coworker showed me this query to look for a certain column:
select *
from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME
like '%id%'
Does this help it run faster, to use the .COLUMNS notation?
thanks a lot?
I agree with Martin. I much prefer this query:
SELECT OBJECT_SCHEMA_NAME(object_id), OBJECT_NAME(object_id), name
FROM sys.columns
WHERE name LIKE '%id%';
The reason I prefer sys. over INFORMATION_SCHEMA.? Mostly because - while the INFORMATION_SCHEMA views are standard - they're already incomplete, and to add insult to injury they don't pick up new features in newer versions of SQL Server. I blogged about it here.
But your question seems to be missing some context in any case. What other methods of "looking for a certain column" are you comparing this to?

Resources