Linked-servers SQL Server 2012 permission? - sql-server

I am trying to understand the linked-servers in SQL Server Studio 2012 that I am using to develop a big report. I have looked through some of the post but I didn't see anything related to permission or how to do it with non-default instance servers that we have. My first question is: can I use create linked-server querying when I only have read permission? Second: I would appreciate if someone can elaborate more on the syntax. Below is the syntax that I am having problem with. Our server name is not just the server name but it has servername\databasename due to IT's reason for a non-default instance (this is what our IT department told me).
SELECT *
FROM [server1\databse1 name].[dbo].[table name]. tab1
INNER JOIN [server2\database2 name].[dbo].[table name] tab2
ON tab1.ID = tab2.ID`
Thank you so much.

can I use create linked-server querying when I only have read permission?
Answer: No you will need sysadmin permissions to add a linked server. If you only have read permissions on the server you will need to ask your DBA to do it for you.
I would appreciate if someone can elaborate more on the syntax. Below is the syntax that I am having problem.....
Your syntax will be something like this...
Assuming databse1Name is located on the Linked server and database2Name is on the server where you are logged on.
SELECT * FROM
[ServerName].[databse1Name].[dbo].[table name]. tab1
INNER JOIN [database2Name].[dbo].[table name] tab2
ON tab1.ID = tab2.ID
If it is a specific Instance on the linked server then you would write your query something like...
SELECT * FROM
[ServerName\InstanceName].[databse1Name].[dbo].[table name]. tab1
INNER JOIN [database2Name].[dbo].[table name] tab2
ON tab1.ID = tab2.ID

Related

How can I get data from 2 different SQL Servers

I have the following situation. I am working with 2 separate SQL servers. Server A hosts the company HR data. There is a view on Server a that provides supervisor info for each employee. I need to get the next supervisor info going up the chain. So I used this to code, I got from the DB admin, to accomplish that
SELECT *
FROM [lawdata].[dbo].[All_Users] ru1
left outer join [lawdata].[dbo].[All_Users] ru2 on ru1.SUPER_EID = ru2.EMP_EID
Now I have data on a separate SQL Server, Server B, that contains some report data the ReportData table contains the employee ID which matches employee ID numbers shown in the view above from Server A. The questions is how can I merge the view from Server A and the Employee ID on Server B so I can link the supervisors to the data rows on Server B.
I have seen this post but just cannot get the syntax right to make it work with my situation
Thanks
You need linked servers. then use
[ServerName].[DatabaseName].[dbo].[tableName]
Create Linked Servers (SQL Server Database Engine)
For this, I'd create an SSIS package to pull down the data from the lawdata server into the database on Server B once a night - probably just a truncate and reload. This way, all of your queries with lawdata data on Server B is localized to one database on one server.
it looks like in your code you did a left outer join on something with itself. Try
SELECT *
FROM [server1].[dbname].[dbo].[tablename] A
left outer join [server2].[dbname].[dbo].[tablename] B on A.columnname = B.columnname
where ["insert where clause here"]
Just in case someone else is trying to solve this same problem here is the solution I came up with; thanks to the suggestion given above
select rd.*, ru1.emp_first, ru1.emp_last, ru1.Super_Last as FirstLineLast,
Super_first as FirstLineFirst,
ru2.Super_Last as SecondLineLast,
2.Super_first as SecondLineFirst
from [TaserEvidence].[dbo].[ReportData] rd left outer join
[soops-lawrept].[lawdata].[dbo].[My_View] ru1 on rd.OwnerBadgeId = ru1.emp_EID
left outer join
[soops-lawrept].[lawdata].[dbo].[rob_users] ru2 on ru1.super_EID = ru2.EMP_EID

SQL Server Management Studio - history of commands run

I have previously altered a table, added a column and modify a stored procedure.
I do not remember exactly which table and which stored procedure,
is there some log in sql management studio about what changes were done in a particular DB?
I have tried what is described here How to see query history in SQL Server Management Studio but i have not found the changes made to the DB
There's a few ways that you can get this information. Firstly you could try the standard reports --> Schema Changes History.
The information for this comes from:
SELECT cat.name AS Category
, b.name AS EventCaptured
, c.name AS ColumnCaptured
FROM fn_trace_geteventinfo(1) AS a
INNER JOIN sys.trace_events AS b
ON a.eventid = b.trace_event_id
INNER JOIN sys.trace_columns AS c
ON a.columnid = c.trace_column_id
INNER JOIN sys.trace_categories AS cat
ON b.category_id = cat.category_id
ORDER BY Category, EventCaptured, ColumnCaptured
Alternatively, query sys.traces to find the location of the default trace and feed this into fn_trace_gettable as per below.
SELECT *
FROM fn_trace_gettable
('C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\LOG\log.trc', default)
You can use Security\Server Audit Specification and enable DATABASE_OBJECT_CHANGE_GROUP audit on your database.
Use following reference in order to use SQL Server server audit.
CREATE SERVER AUDIT SPECIFICATION (Transact-SQL)
Create a Server Audit and Server Audit Specification
You can use the modify_date column in sys.objects table
SELECT *
FROM SYS.OBJECTS
WHERE Modify_Date BETWEEN <date_of_modification> AND <date_of_modification> + 1
and then you can try to narrow it down.
You can be even more specific and run the query for just tables and stored procedures.
SELECT *
FROM SYS.objects
WHERE TYPE IN ('IT', 'S', 'U', 'P', 'PC', 'X')
AND modify_date BETWEEN '10-Jun-2014' AND '11-Jun-2014'
I develop SSMSBoost add-in for SSMS and we have "Executed Query history" there. All actions are logged with timestamp, connection information and execution result. This will certainly only work, if you do all changes from SSMS with SSMSBoost installed. If someone will perform changes from other machine you will not see them, until he uses SSMSBoost as well and you share execution history.

Local SQL Server: The specified procedure could not be found

This problem has appeared on my PC a few days ago, without any changes I have made to the Visual Studio/SQL Server settings.
When trying to perform any manual operation on the database file (*.mdf) in Visual Studio, I get the following error:
The specified procedure could not be found. (Exception from HRESULT: 0x8007007F)
(For example, when trying to create a new table, or when showing an existing table's data)
How I can fix this error?
Be sure you or someone else has not changed your rights on master. In order to add anything a record is added to that table.
Addendum:
You can run the following script to determine who has what permissions and whether they are implicit or explicit.
WITH perms_cte as
(
select USER_NAME(p.grantee_principal_id) AS principal_name,
dp.principal_id,
dp.type_desc AS principal_type_desc,
p.class_desc,
OBJECT_NAME(p.major_id) AS object_name,
p.permission_name,
p.state_desc AS permission_state_desc
from sys.database_permissions p
inner JOIN sys.database_principals dp
on p.grantee_principal_id = dp.principal_id
)
--users
SELECT p.principal_name, p.principal_type_desc, p.class_desc, p.[object_name], p.permission_name, p.permission_state_desc, cast(NULL as sysname) as role_name
FROM perms_cte p
WHERE principal_type_desc <> 'DATABASE_ROLE'
UNION
--role members
SELECT rm.member_principal_name, rm.principal_type_desc, p.class_desc, p.object_name, p.permission_name, p.permission_state_desc,rm.role_name
FROM perms_cte p
right outer JOIN (
select role_principal_id, dp.type_desc as principal_type_desc, member_principal_id,user_name(member_principal_id) as member_principal_name,user_name(role_principal_id) as role_name--,*
from sys.database_role_members rm
INNER JOIN sys.database_principals dp
ON rm.member_principal_id = dp.principal_id
) rm
ON rm.role_principal_id = p.principal_id
order by 1
--- thanks to Jamie Thomson for this ditty
A more few suggestions;
Trace the call using profiler and confirm you are connecting as the user you think you are - sp_who2 might be another way to verify that.
Verify your process is in the correct database. Use the c# connection and run SELECT DB_NAME() - write the result somewhere you can read to confirm.
If this works from one environment but not another I would strongly suspect the connection string.
Check that you do not have authentication errors reported in your SQL logs. These again would indicate possible connection issues.
The conventional wisdom on this error is that it likely reflects a lost or corrupted DLL (in either SQL Server or Visual Studio). And the SOP is to reinstall, though it seems that that does not always work either.
Try to run Visual Studio as administrator
Right click Visual Studio --> Run as Administrator.
Try to connect to the database in SQL Server Management Studio. That'll at least narrow down whether it's a database permission issue or something else. Also, check to confirm that the database exists and you have permission to access it. (Like Joe suggested.)
Assuming that checks out... My googling found a guy with a very similar sounding problem. He said that the runas administrator thing Adel suggested worked for him, but there were other issues that could also cause the error message, including VS not being able to find the IIS virtual server specified in the Web Application Project file (permissions? renamed?). Confirm that the file exists and you have permission to access it.
http://connect.microsoft.com/VisualStudio/feedback/details/317124/system-runtime-interopservices-comexception-in-webapplication-project

How to make a select query for sql and access databases?

Using SQL server 2000 and Access 2003
Access Database Name - History.mdb
Access Table Name - Events
SQL Database Name - Star.mdf
SQL Table Name - Person
I want to take the field from person table, and include in Events table by using inner join
Tried Query
Select * from Events inner join person where events.id = person.id
So How to make a query for access and sql databases.
I want to make a Select query in access only. Not an sql Database.
Need Query Help?
While you can (possible, should -- why?) use a linked table, there are as ever more than one way to skin a cat. Here's another approach: put the connection details into the query test e.g. something like
SELECT *
FROM [ODBC;Driver={SQL Server};SERVER=MyServer;DATABASE=Star;UID=MyUsername;Pwd=MyPassword;].Person AS P1
INNER JOIN
[MS Access;DATABASE=C:\History;].[Events] AS E1
ON S1.seq = S2.seq
WHERE E1.id = P1.id;
You can set up a linked table in Access to your SQL Server, and the instructions on how to do so vary slightly in Access versions. Look in the help file for "Linked Table", or go here if you have Access 2007.
Once you have a linked table set up, you'll be able to access the SQL Server table in your query. Note that optimizing a linked table join takes some work.
You can create a linked table in Access, that points to the table in SQL. The rest you can achieve in the query designer.
You should add the msaccess db as a remote server.
then you can do that join

How can I get a list of all of the user databases via t-sql?

I want to get a list of all of the user databases from an mssql server instance. What's the best way to do this?
I know I can select from sys.databases, but I don't see any way to filter out system databases besides hardcoding a list of names to exclude.
I need the script to work on 2000/2005 and 2008.
If the approach I listed above is the only way to go, what are list of names I should exclude? I don't know if 2005 or 2008 added any new system databases off the top of my head.
Was looking in to this again today and decided to profile what Management Studio was doing to populate the Object Explorer details.
Turns out the solution Microsoft have implemented is pretty simplistic and boils down to the following:
SELECT *
FROM master.sys.databases
WHERE Cast(CASE WHEN name IN ('master', 'model', 'msdb', 'tempdb') THEN 1 ELSE is_distributor END As bit) = 0
Please note that this was performed using SSMS 2008R2 (10.50.4033.0).
The first query will return a table with data regarding all of the databases on the instance:
Select *
From sys.databases
From this table you'll notice you can narrow down the scope of data you're looking for by using the WHERE clause. For example, the following queries will essentially return the same result table (the one you're most likely looking for):
Select *
From sys.databases
Where database_id > 5
Select *
From sys.databases
Where len(owner_sid)>1
These queries will work in SQL Server 2008 and 2012.
On SQL Server 2008 R2 Express, looks like I cannot reliably use any of the above methods. INFORMATION_SCHEMA.SCHEMATA only shows me information in the current database, db_id (database_id) #5 is my first user database, and owner_sid on two of my user databases on one of my mirrored databases (running on SQL Server 2008 R2 Standard) shows owner_sid = 1 for my two most recently created databases. (PablolnNZ's comment above is correct: I did not set an explicit owner for those two databases so it still shows as having an owner of 'sa'.)
The only reliable means I was able to use was the following:
SELECT name FROM sys.databases
WHERE name NOT IN ('master', 'model', 'tempdb', 'msdb', 'Resource')
This works in 2005, not 100% sure about the other versions but I think it will fly. It's a bit of a hack but might get you what you need:
select * from sys.databases where len(owner_sid)>1
As nasty as it sounds to hardcode things. The names and number of system databases has been fairly consistent for several versions of SQL. However, if that is too unpleasant you could semi-hardcode them into a table and then plug that into your query.
Not sure if you can offhand. One note -- on 2k you'll have to use master.dbo.sysdatabases and not master.sys.databases (which doesn't exist in 2k).
Starting with SQL Server 2008 you have access to a view called sys.databases which when joined with sys.server_principals can eliminate the databases owned by sa, which you can (most often) safely discern are the "system databases". Thus, allowing you to filter these items out.
select
d.name
,d.database_id
from
sys.databases d
join
sys.server_principals p
on p.sid = d.owner_sid
where
p.name <> 'sa';

Resources