Running a stored proc using opendatasoirce

  • Good Day guys,

    Very excited , that I get a chance to actually be active by posting my very first question. I have been using this forum for quite a while now. Well , enough , here goes.

    I want to retrieve database stats using the below command

    EXEC sp_MSforeachdb '

    USE ?

    SELECT

    CASE WHEN CONVERT(varchar(250), SERVERPROPERTY(''ComputerNamePhysicalNetBIOS'')) COLLATE Latin1_General_CI_AS LIKE ''D%'' THEN ''Dev''

    WHEN CONVERT(varchar(250), SERVERPROPERTY(''ComputerNamePhysicalNetBIOS'')) COLLATE Latin1_General_CI_AS LIKE ''T%'' THEN ''Test''

    WHEN CONVERT(varchar(250), SERVERPROPERTY(''ComputerNamePhysicalNetBIOS'')) COLLATE Latin1_General_CI_AS LIKE ''P%'' THEN ''Prod''

    WHEN CONVERT(varchar(250), SERVERPROPERTY(''ComputerNamePhysicalNetBIOS'')) COLLATE Latin1_General_CI_AS LIKE ''PP%'' THEN ''Pre-Prod''

    ELSE ''Uknown''END AS [Environment],

    CONVERT(varchar(250), SERVERPROPERTY(''ComputerNamePhysicalNetBIOS'')) COLLATE Latin1_General_CI_AS AS [CurrentHost],

    Getdate() as Extract_Date,

    CONVERT(varchar(250), DB_NAME(v.database_id)) COLLATE Latin1_General_CI_AS [DB],

    CONVERT(varchar(250), df.type_desc) COLLATE Latin1_General_CI_AS [FileType],

    CONVERT(varchar(250), f.name) COLLATE Latin1_General_CI_AS [Name],

    CONVERT(varchar(250), v.volume_mount_point) COLLATE Latin1_General_CI_AS [VolumeOrDrive],

    CONVERT(varchar(250), f.[Filename]) COLLATE Latin1_General_CI_AS [Filename],

    CONVERT(Decimal(15,2), ROUND(f.Size/128.000,2)) [File Size (MB)],

    CONVERT(Decimal(15,2), ROUND(FILEPROPERTY(f.Name,''SpaceUsed'')/128.000,2)) [Space Used In File (MB)],

    CONVERT(Decimal(15,2), ROUND((f.Size-FILEPROPERTY(f.Name,''SpaceUsed''))/128.000,2)) [Available Space In File (MB)],

    CONVERT(Decimal(15,2), v.available_bytes/1048576.0) [Drive Free Space (MB)]

    INTO dbo.dbstats

    FROM sys.sysfiles f WITH (NOLOCK)

    INNER JOIN sys.database_files df ON df.file_id = f.fileid

    CROSS APPLY sys.dm_os_volume_stats(DB_ID(), f.fileid) v;'

    I need to get this code running dynamically through all servers , using opendatasource as linked servers are not allowed. Has anybody went through this before?

    SELECT * FROM OPENDATASOURCE(

    'SQLOLEDB',

    'Data Source=ServerName;user id=User;password=Password1'

    )

    The whole idea , is basically kicking off a dynamic procedure via opendatasource

    Thanks,

    Tate

  • Hi guys,

    I think , this was my laziness to sort out the dynamic logic. I have managed to get the dynamic kind of working after testing it with a different method, but now I am getting this error below

    The metadata could not be determined because statement 'exec(@precommand)' in procedure 'sp_MSforeachdb' contains dynamic SQL. Consider using the WITH RESULT SETS clause to explicitly describe the result set.

    If anyone has any light of how I can do it differently , please let me know

    Thanks,

    Tate

  • I've setup something similar before, but I used OPENROWSET instead. I tried a few different things but I found if I was calling a stored procedure I had to use SET FMTONLY OFF and also store things in a temp table:

    DECLARE @instance NVARCHAR(40), @ver smallint, @sqlcmd NVARCHAR(1000);

    DECLARE cur_instance CURSOR FAST_FORWARD FOR

    SELECT ic.instance, ic.[version]

    FROM InstanceConfig ic

    LEFT OUTER JOIN dbo.FileStats fs ON ic.instance = fs.instance AND fs.run_date = DateAdd(day, DateDiff(day, 0, GetDate()), 0)

    WHERE ic.collect_file_stats = 1

    AND fs.instance IS NULL;

    OPEN cur_instance;

    FETCH NEXT FROM cur_instance INTO @instance, @ver;

    WHILE @@FETCH_STATUS = 0

    BEGIN

    IF @ver >= 2012

    SET @sqlcmd = N'INSERT INTO dbo.FileStats SELECT * FROM OPENROWSET (''SQLNCLI'',''SERVER=' + @instance + N';Trusted_Connection=yes'',''msdb.dbo.sp_all_db_filespace

    WITH RESULT SETS (([instance] varchar(40), [database] varchar(40), [run_date] date, [file_id] int, [file_name] varchar(60), [file_type] varchar(60), [drive] char(1), [size_mb] int, [used_mb] int, [available_mb] int, [growth] int, [is_percent_growth] bit, [state_desc] varchar(60)))'') fd';

    ELSE

    SET @sqlcmd = N'INSERT INTO dbo.FileStats SELECT * FROM OPENROWSET (''SQLNCLI'',''SERVER=' + @instance + N';Trusted_Connection=yes'',''SET FMTONLY OFF;

    CREATE TABLE #FileStats([instance] varchar(40), [database] varchar(40), [run_date] date, [file_id] int, [file_name] varchar(60), [file_type] varchar(60), [drive] char(1), [size_mb] int, [used_mb] int, [available_mb] int, [growth] int, [is_percent_growth] bit, [state_desc] varchar(60));

    EXECUTE sp_msforeachdb ''''USE [?]; INSERT INTO #FileStats SELECT CAST(SERVERPROPERTY(''''''''ServerName'''''''') AS varchar(40)), LEFT(DB_NAME(),40), CAST(DateDiff(day, 0, GETDATE()) AS DateTime), f.file_id, LEFT(f.name,60), f.type_desc, LEFT(f.physical_name,1), f.size/128, FILEPROPERTY(f.name, ''''''''SpaceUsed'''''''')/128, f.size/128 - FILEPROPERTY(f.name, ''''''''SpaceUsed'''''''')/128, CASE WHEN f.is_percent_growth = 1 THEN f.growth ELSE f.growth / 128 END, f.is_percent_growth, f.state_desc FROM sys.database_files f'''';

    SELECT * FROM #FileStats;DROP TABLE #FileStats'') fd';

    EXEC sp_executesql @sqlcmd;

    FETCH NEXT FROM cur_instance INTO @instance, @ver;

    END

    CLOSE cur_instance;

    DEALLOCATE cur_instance;

  • Hi Chris,

    Thanks for your response, much appreciated! I will be leveraging of some of your method, but tell me something. This proc 'msdb.dbo.sp_all_db_filespace' , did you manually create in on your msdb, but with the same logic as 'sp_msforeachdb' ?

    Chris Harshman (10/7/2016)


    I've setup something similar before, but I used OPENROWSET instead. I tried a few different things but I found if I was calling a stored procedure I had to use SET FMTONLY OFF and also store things in a temp table:

    DECLARE @instance NVARCHAR(40), @ver smallint, @sqlcmd NVARCHAR(1000);

    DECLARE cur_instance CURSOR FAST_FORWARD FOR

    SELECT ic.instance, ic.[version]

    FROM InstanceConfig ic

    LEFT OUTER JOIN dbo.FileStats fs ON ic.instance = fs.instance AND fs.run_date = DateAdd(day, DateDiff(day, 0, GetDate()), 0)

    WHERE ic.collect_file_stats = 1

    AND fs.instance IS NULL;

    OPEN cur_instance;

    FETCH NEXT FROM cur_instance INTO @instance, @ver;

    WHILE @@FETCH_STATUS = 0

    BEGIN

    IF @ver >= 2012

    SET @sqlcmd = N'INSERT INTO dbo.FileStats SELECT * FROM OPENROWSET (''SQLNCLI'',''SERVER=' + @instance + N';Trusted_Connection=yes'',''msdb.dbo.sp_all_db_filespace

    WITH RESULT SETS (([instance] varchar(40), [database] varchar(40), [run_date] date, [file_id] int, [file_name] varchar(60), [file_type] varchar(60), [drive] char(1), [size_mb] int, [used_mb] int, [available_mb] int, [growth] int, [is_percent_growth] bit, [state_desc] varchar(60)))'') fd';

    ELSE

    SET @sqlcmd = N'INSERT INTO dbo.FileStats SELECT * FROM OPENROWSET (''SQLNCLI'',''SERVER=' + @instance + N';Trusted_Connection=yes'',''SET FMTONLY OFF;

    CREATE TABLE #FileStats([instance] varchar(40), [database] varchar(40), [run_date] date, [file_id] int, [file_name] varchar(60), [file_type] varchar(60), [drive] char(1), [size_mb] int, [used_mb] int, [available_mb] int, [growth] int, [is_percent_growth] bit, [state_desc] varchar(60));

    EXECUTE sp_msforeachdb ''''USE [?]; INSERT INTO #FileStats SELECT CAST(SERVERPROPERTY(''''''''ServerName'''''''') AS varchar(40)), LEFT(DB_NAME(),40), CAST(DateDiff(day, 0, GETDATE()) AS DateTime), f.file_id, LEFT(f.name,60), f.type_desc, LEFT(f.physical_name,1), f.size/128, FILEPROPERTY(f.name, ''''''''SpaceUsed'''''''')/128, f.size/128 - FILEPROPERTY(f.name, ''''''''SpaceUsed'''''''')/128, CASE WHEN f.is_percent_growth = 1 THEN f.growth ELSE f.growth / 128 END, f.is_percent_growth, f.state_desc FROM sys.database_files f'''';

    SELECT * FROM #FileStats;DROP TABLE #FileStats'') fd';

    EXEC sp_executesql @sqlcmd;

    FETCH NEXT FROM cur_instance INTO @instance, @ver;

    END

    CLOSE cur_instance;

    DEALLOCATE cur_instance;

    Thanks,

    Tate

  • I'm sorry, I forgot this was a custom stored proc. It's basically doing the sp_foreachdb loop outside of the remote procedure call:

    CREATE PROCEDURE dbo.sp_all_db_filespace AS

    BEGIN

    CREATE TABLE #FileStats([instance] varchar(40), [database] varchar(40), [run_date] date, [file_id] int, [file_name] varchar(60), [file_type] varchar(60), [drive] char(1), [size_mb] int, [used_mb] int, [available_mb] int, [growth] int, [is_percent_grow

    th] bit, [state_desc] varchar(60));

    EXECUTE sp_msforeachdb 'USE [?]; INSERT INTO #FileStats SELECT CAST(SERVERPROPERTY(''ServerName'') AS varchar(40)), LEFT(DB_NAME(),40), CAST(DateDiff(day, 0, GETDATE()) AS DateTime), f.file_id, LEFT(f.name,60), f.type_desc, LEFT(f.physical_name,1), f.

    size/128, FILEPROPERTY(f.name, ''SpaceUsed'')/128, f.size/128 - FILEPROPERTY(f.name, ''SpaceUsed'')/128, CASE WHEN f.is_percent_growth = 1 THEN f.growth ELSE f.growth / 128 END, f.is_percent_growth, f.state_desc FROM sys.database_files f';

    SELECT * FROM #FileStats;

    DROP TABLE #FileStats

    END

  • Hi Chris,

    You are a lifesaver , it works wonders now. Thanks for your assistance , this is highly appreciated

    Chris Harshman (10/12/2016)


    I'm sorry, I forgot this was a custom stored proc. It's basically doing the sp_foreachdb loop outside of the remote procedure call:

    CREATE PROCEDURE dbo.sp_all_db_filespace AS

    BEGIN

    CREATE TABLE #FileStats([instance] varchar(40), [database] varchar(40), [run_date] date, [file_id] int, [file_name] varchar(60), [file_type] varchar(60), [drive] char(1), [size_mb] int, [used_mb] int, [available_mb] int, [growth] int, [is_percent_grow

    th] bit, [state_desc] varchar(60));

    EXECUTE sp_msforeachdb 'USE [?]; INSERT INTO #FileStats SELECT CAST(SERVERPROPERTY(''ServerName'') AS varchar(40)), LEFT(DB_NAME(),40), CAST(DateDiff(day, 0, GETDATE()) AS DateTime), f.file_id, LEFT(f.name,60), f.type_desc, LEFT(f.physical_name,1), f.

    size/128, FILEPROPERTY(f.name, ''SpaceUsed'')/128, f.size/128 - FILEPROPERTY(f.name, ''SpaceUsed'')/128, CASE WHEN f.is_percent_growth = 1 THEN f.growth ELSE f.growth / 128 END, f.is_percent_growth, f.state_desc FROM sys.database_files f';

    SELECT * FROM #FileStats;

    DROP TABLE #FileStats

    END

    Many thanks,

    Tate

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic. Login to reply