SSIS - OLEDB Source - how to use sql query with variables? - sql

I have this query that I want to export its contents to a table:
DECLARE #bdname VARCHAR(50)
SET #bdname = ?
SELECT
#bdname,
CONVERT(CHAR(30), dp2.name),
CONVERT(CHAR(20), dp.name)
FROM
sys.database_principals AS dp
INNER JOIN
sys.database_role_members AS drm ON dp.principal_id = drm.role_principal_id
INNER JOIN
sys.database_principals AS dp2 ON drm.member_principal_id = dp2.principal_id
WHERE
(dp2.principal_id > 4) AND (dp2.type <> 'R')
If I put this as part of a Execute SQL Task, it goes ok, but I can't (don't know how) then map the results into something that I can export to a SQL table.
Can anyone guide me on how can I put the results of this query into a table? It's because if I use dataflow and ole db source, it does not accept this type of query.
Any help would be much appreciated.
Thanks

Add a dataflow task, inside it add an Oledb source and an Oledb destination.
Add a variable of type string , set Evaluate as expression to true and assign the following expression:
"SELECT '" + #[User::bdname] + "' , convert(char(30),dp2.name), convert(char(20),dp.name)
FROM sys.database_principals AS dp INNER JOIN
sys.database_role_members AS drm ON dp.principal_id = drm.role_principal_id
INNER JoIN
sys.database_principals AS dp2 ON drm.member_principal_id = dp2.principal_id
WHERE (dp2.principal_id > 4) AND (dp2.type <> 'R')"
(Assuming bdname value is stored in user::bdname variable)
In the Oledb source set the source type to Sql command from variable and choose the created variable
Map the oledb source to the oledb destination
UPDATE 1
After reading your comment "...This foreach loop will query the sys.databases for all the user databases, and it is supposed to iterate that variable, to get the permissions".
To iterate over databases you have to add an Execute SQL Task with an SQL Command
SELECT name from sys.databases
and set the Result Set to Full Result Set , and assign the Result Set to a variable of type Object
Link this Execute SQL Task to the ForEach Loop Container
In the foreach Loop Container change the enumerator type to Ado enumerator and choose the object variable as source
Also don't forget to set the Dataflow task Delay Validation property to True
UPDATE 2 (workaround)
Try joining your query with sys.databases instead of using Foreach loop container (i don't know if it achieve what you want to do)
SELECT db.name, convert(char(30),dp2.name), convert(char(20),dp.name)
FROM sys.database_principals AS dp INNER JOIN
sys.database_role_members AS drm ON dp.principal_id = drm.role_principal_id
INNER JoIN
sys.database_principals AS dp2 ON drm.member_principal_id = dp2.principal_id
INNER JOIN sys.databases as db ON db.owner_sid = dp2.sid
WHERE (dp2.principal_id > 4) AND (dp2.type <> 'R')

Related

how to find the list of stored procedures with public execute permission

I have a db with more than 1000s of stored procedures.
Need a query to find the list of stored procedures which has public execute permission.
Query I tried which didn't give me clear output.
select name,
has_perms_by_name(name, 'OBJECT', 'EXECUTE') as has_execute,
has_perms_by_name(name, 'OBJECT', 'VIEW DEFINITION') as has_view_definition
from sys.procedures
Not sure why you got voted down, seems like a reasonable question to me.
You'll need something along the lines of:
DECLARE #principal_id int
SELECT #principal_id = principal_id
FROM sys.database_principals
WHERE name = 'public'
SELECT o.name,
dp.permission_name,
dp.state_desc
FROM sys.objects o
JOIN sys.database_permissions dp
ON dp.class = 1
AND dp.major_id = o.object_id
AND dp.grantee_principal_id = #principal_id
AND dp.type = 'EX' -- execute
AND dp.state IN ('G', 'W')
WHERE o.type = 'P' -- stored procedures

Query to get the information of Databases used by Stored Procedure in SQL server 2005

Is there any query in SQL server 2005 that returns the list of Stored procedures in the particular database along with the name of databases whose objects are getting used in the stored procedure.
That is how to get all procedure names:
select *
from DatabaseName.information_schema.routines
where routine_type = 'PROCEDURE'
I will check now, if there is any way to check their code for table names.
you can use this query
it will show all dependencies even to the columns
SELECT
--SP, View, or Function
ReferencingName = o.name,
ReferencingType = o.type_desc,
--Referenced Field
ref.referenced_database_name, --will be null if the DB is not explicitly called out
ref.referenced_schema_name, --will be null or blank if the DB is not explicitly called out
ref.referenced_entity_name,
ref.referenced_minor_name
FROM sys.objects AS o
cross apply sys.dm_sql_referenced_entities('dbo.' + o.name, 'Object') ref
where o.type = 'p'
-- for other database object types use below line
-- o.type in ('FN','IF','V','P','TF')
works for single database
select *
from information_schema.routines
where routine_type = 'PROCEDURE'
This is not a simple thing to do reliably in SQL Server 2005. You might want to look at commercial products such as ApexSQL Clean or SQL Dependency Tracker.
In SQL Server 2008 you could try using the sys.sql_expression_dependencies dynamic management view. For example,
select
quotename(s.name) + N'.' + quotename(o.name) as ProcedureName,
ed.referenced_server_name,
ed.referenced_database_name,
ed.referenced_schema_name,
ed.referenced_entity_name
from sys.sql_expression_dependencies ed
inner join sys.objects o on o.object_id = ed.referencing_id
inner join sys.schemas s on s.schema_id = o.schema_id
where
o.type = 'P'
Hope this helps,
Rhys

Insight.database executing sql function

To execute sql function or procedure Insight database in the guts executes a query to get info about stored procedures or function and its parameters.
But in the case of sql function query returns the first parameter name empty.
for example:
exec sp_executesql N'SELECT ParameterName = p.Name, SchemaName = s.name, TypeName = t.Name
FROM sys.parameters p
LEFT JOIN sys.types t ON (p.user_type_id = t.user_type_id)
LEFT JOIN sys.schemas s ON (t.schema_id = s.schema_id)
WHERE p.object_id = OBJECT_ID(#Name)',N'#Name nvarchar(4000)', #Name=N'dbo.FuncName'
This query returns parameters list, but first parameter is empty.
In this case Insight.Database fails to execute query.
Is there a way to resolve it without using adapter?
As far as I know, there's no way for a SqlCommand to execute a SQL function directly (regardless of whether the parameters are correct).
To call a function directly, you would need to use a SQL statement. Example:
select * from dbo.fn_GetUserId_Username(#Username)
In this case, Insight should pick up the parameters correctly.

Find and replace content in stored procedures ms sql server

I want to rename tables and views which are used in stored procedures. Is there any way to find and replace table names in stored procedures, maybe there is tool for ms sql server (i'm using ms sql server 2012).
SQL Server might not allow you to directly UPDATE the object definitions (Views and Stored Proceduress in your case) present in the System catalogs even after setting the 'Allow Updates' option to 1.
The following code will generate the required ALTER Script and you can run them manually after reviewing the definitions ([ModifiedDefinition] )or u can loop through each value of [ModifiedDefinition] and run it using sp_executesql.
SELECT
b.Name AS [ObjectName],
CASE WHEN b.type ='p' THEN 'Stored Procedure'
WHEN b.type ='v' THEN 'View'
ELSE b.TYPE
END AS [ObjectType]
,a.definition AS [Definition]
,Replace ((REPLACE(definition,'OLD Value','New Value')),'Create','ALTER') AS [ModifiedDefinition]
FROM sys.sql_modules a
JOIN
( select type, name,object_id
from sys.objects
where type in (
'p' -- procedures
,'v'--views
)
and is_ms_shipped = 0
)b
ON a.object_id=b.object_id
And as always, be careful with production data and take backups before performing bulk changes on object definitions!!
You can use DBvisualizer .. it pretty much works with all databases and with ms sql too, you can do all you mentioned by using this.
I answered this on another topic (https://stackoverflow.com/a/67728039/11165834) , I do it using the following script:
DECLARE #queryDef NVARCHAR(max)
WHILE EXISTS (
SELECT 1
FROM sys.sql_modules sm
JOIN sys.objects o ON sm.object_id = o.object_id
WHERE sm.definition LIKE '%TEXT_TO_REPLACE%'
AND o.type = 'V'
)
BEGIN
-- TO ALTER THE VIEW AUTOMATICALLY
SET #queryDef = ( SELECT TOP 1 Replace (Replace (sm.definition, 'CREATE VIEW', 'ALTER VIEW'),
'TEXT_TO_REPLACE',
'NEW_TEXT')
FROM sys.sql_modules sm
JOIN sys.objects o ON sm.object_id = o.object_id
WHERE sm.definition LIKE '%TEXT_TO_REPLACE%'
AND o.type = 'V')
EXEC (#queryDef)
END
I use it to replace procedures/views when I restore a backup from production into tests databases.
As #S.A said, be verry careful because is not a verry safe way.
Change the "o.type" and "Replace (sm.definition, 'CREATE VIEW', 'ALTER VIEW'" accordingly to your need

How can I get the 'External name' of a SQL CLR trigger?

I have created a SQL CLR trigger with the follow SQL:
GO
CREATE TRIGGER AuditAccountsTable
ON [dbo].[Accounts]
FOR INSERT,DELETE,UPDATE
AS
EXTERNAL NAME namespace.Triggers.AuditTrigger
I am trying to query:
select * from sys.triggers
Is there a way to find the: EXTERNAL NAME namespace.Triggers.AuditTrigger on the trigger from querying in the DB?
I can't be sure as I don't have a place to test this, but does the text column returned below get you close to what you're looking for?
select t.name, c.text
from sys.triggers t
inner join sys.syscomments c
on t.object_id = c.id
where t.type_desc = 'CLR_TRIGGER'
Unlike T-SQL "modules" such as Stored Procedures and Functions, the SQLCLR T-SQL wrapper objects do not have their CREATE statements stored in the database. This is why you cannot access them via sys.sql_modules, OBJECT_DEFINITION, or the deprecated-since-SQL-Server-2005-and-should-not-be-used sys.syscomments. This is why SQLCLR Stored Procedures and Functions need to have their parameter default values stored in sys.parameters
Instead, CREATE statements for SQLCLR T-SQL wrapper objects are inferred from meta-data, just like Indexes, Primary Keys, Foreign Keys, etc.
You can get all of the parts of the CREATE TRIGGER statement from the following query:
SELECT OBJECT_SCHEMA_NAME(st.[object_id]) AS [SchemaName],
st.[name] AS [TriggerName],
OBJECT_SCHEMA_NAME(st.parent_id) AS [ParentSchemaName],
OBJECT_NAME(st.parent_id) AS [ParentName],
st.is_instead_of_trigger,
SUBSTRING((
SELECT N', ' + ste.[type_desc]
FROM sys.trigger_events ste
WHERE ste.[object_id] = st.[object_id]
FOR XML PATH ('')
), 3, 500) AS [Actions],
QUOTENAME(sa.name) AS [AssemblyName],
QUOTENAME(sam.assembly_class) AS [AssemblyClass],
QUOTENAME(sam.assembly_method) AS [AssemblyMethod]
FROM sys.triggers st
INNER JOIN sys.assembly_modules sam
ON sam.[object_id] = st.[object_id]
INNER JOIN sys.assemblies sa
ON sa.[assembly_id] = sam.[assembly_id]
WHERE st.parent_class = 1; --- OBJECT_OR_COLUMN