Montag, 31. Mai 2010

Determine the rowcounts for all tables of a SQL-Server Database

Of course you can loop through all tables of a database, compose a select statement to query count(*) of each single table and end in some time-out problem at some customer database. 
There is a quick solution without any loops:

SELECT o.name, max(i.rows) FROM dbo.sysindexes i  join sysobjects o on i.id = o.id
group by o.id, o.name
order by 1
 I'm not 100 % certain that the results are exact in all cases, but for me it works well.

Cf. http://entwickler-forum.de/showthread.php?t=18850

Dienstag, 18. Mai 2010

Generating the column list for an SQL-Server Table

How often did you use in query analyzer extra | options | results | userdefined delimiter| ,
to the column list of a table in a form ready to replace the '*' in

Select * from mytable
by the complete column list?

Well I definitely did it too often. It is so easy to write a stored procedure for the same purpose:

if object_id('build_columnlist') > 0
    drop procedure build_columnlist
go

create procedure dbo.build_columnlist @table_name sysname
as
begin
declare @cols varchar(max)  -- varchar(8000) for sql server 2000

select @cols = case when @cols  is null then c.name else @cols + ', ' + c.name end
from syscolumns c join sysobjects o on c.id = o.id
where o.name = @table_name order by colorder

select @cols
end

go

now just type

exec build_columnlist 'mytable'
and when you display the result as text, it is there ready to copy and past.

Oops did you change extra | options | max characters pro column to 8000 ?
That was for Query Analyzer, SQL-Managemantstudio has a similar setting. 

And note the trick of updating a variable using a select statement.

defaults are always wrong.

Bernd

Samstag, 15. Mai 2010

Is your Clientready for SQLPSX with Oracle?

For those, who do not know, SQLPSX is a Codeplex project using PowerShell to access SQL-Server Databases using SMO and ADO.NET to acces SQL-Servers for adminstrative tasks and to execute querys on them. 

The newest release brought some integration into ISE the grafical Interactive Scripting Environment. You may look at http://www.youtube.com/watch?v=1KcNSHn7oTA to get an impression.

The modules OracleClient and OracleISE are new too and aim at establishing connections to and executing simple queries on Oracle servers. (Stored procedures returning refcursors and parameters are not yet supported).

Today I'm not describing how to use these modules, but I provide a test for you, to check if the needed components are installed.

The needed components are called Oracle Data Access Components
You need a computer with a orcale client including these components, you need PowerShell V2 running on it and you need how to connect to an Oracle Server using TNS names. 

Now lets execute a litte PowerShell, to see if the Oracle.DataAccess is found on your system



$a = [System.Reflection.Assembly]::LoadWithPartialName("Oracle.DataAccess")             
$a | fl            

If you get something like

CodeBase               : file:///C:/Windows/assembly/GAC_32/Oracle.DataAccess/2
                         .111.6.0__89b483f429c47342/Oracle.DataAccess.dll
EntryPoint             :
EscapedCodeBase        : file:///C:/Windows/assembly/GAC_32/Oracle.DataAccess/2
                         .111.6.0__89b483f429c47342/Oracle.DataAccess.dll
FullName               : Oracle.DataAccess, Version=2.111.6.0, Culture=neutral,
                          PublicKeyToken=89b483f429c47342
GlobalAssemblyCache    : True
HostContext            : 0
ImageFileMachine       :
ImageRuntimeVersion    : v2.0.50727
Location               : C:\Windows\assembly\GAC_32\Oracle.DataAccess\2.111.6.0
                         __89b483f429c47342\Oracle.DataAccess.dll
ManifestModule         : Oracle.DataAccess.dll
MetadataToken          :
PortableExecutableKind :
ReflectionOnly         : False
the needed assembly is present and you can start to wait for me telling you how to use the modules.

Bernd

Sonntag, 9. Mai 2010

About the use of SQL-Server Print Statement

In the old days, when I did my ad-hoc SQL using T-SQL in the Query-Analyzer, it was natural to use print statements, when to give back some feedback to the user.

Today using SQL-Server Management Studio, half the time I display the results in grid and as long as it looks reasonable, I won't switch to the message tab.

With SQL-Server the use  print in T-SQL is rather easy. While in former days you could only emit one string or variable, with todays versions you can use expressions.

I'm not going to speak about Orcales DBMS_OUTPUT package in length here. Remember SET server output on. And OK with 10 g they even got SET SERVEROUTPUT ON SIZE UNLIMITED, i.e. it became an option to use.

But acessing your database from applications or a PowerShell module like SQLPSX,it becomes more difficult to collect the print output.
For SQL-Server it would be possible, that means I know code to get the output.
While with Oracle I have only some vague ideas, how to do it (requiring to use connections) .

Conculsion: I'm starting to rewrite my scripts, using select @msg msg instead of print @msg.

Bernd

Samstag, 8. Mai 2010

sel tablename, 'comma-separated-list-of-columnnumbers'

And now the promised stored procedure:

if object_id ('sel') > 0
    drop procedure sel
go

create procedure dbo.sel (
    @tablename sysname,
    @mode varchar(255),
    @order int = 1,
    @where varchar(1000) = ''
) as
begin
    -- Bernd Kriszio 2010-05-07
    declare @cmd varchar(8000)
    declare @columnquery varchar(8000)
    declare @cnt integer
    declare @t_Name sysname
    declare @column_Name sysname
    declare @type integer
    Declare @anz integer

    Declare @table_names table(bez sysname)

    insert into @table_names select name from sysobjects where type in ('U', 'V') and name like (@tablename + '%')

    select @anz = count(1) from  @table_names
    if (@anz) = 1
    begin
        set @t_Name = (select bez from @table_names)
        Print @t_Name
    end
    else if (@anz > 0)
    begin
        Select 'ambigious '+ bez from @table_names
        return
     end

    if substring(@mode,1,1) = '*'
    begin
        set @cmd = 'Select * from ' + @t_Name + ' ' + @where + ' order by ' + str(@order)
        print @cmd 
        exec (@cmd)
    end

    else
    begin
        set @cmd = ''
        if (Select count(*) from splitColumnNumberList(@mode, ',')) = 1
        begin
            set @cnt = @mode
            declare column_cursor cursor for
                select c.name from syscolumns c join sysobjects o on c.id = o.id where o.name = @t_Name and colorder <= @cnt
        end
        else
            declare column_cursor cursor for
                select c.name from syscolumns c
                    join sysobjects o on c.id = o.id
                    join splitColumnNumberList( @mode, ',') on colid = value
                where o.name = @t_Name
                order by lfd
        open column_cursor
        FETCH NEXT From column_cursor into @column_Name
        WHILE @@FETCH_STATUS = 0
        begin
            --Print @column_Name
            set @cmd = case when @cmd  = '' then 'Select ' + @column_Name else @cmd + ', ' + @column_Name end
            FETCH NEXT From column_cursor into @column_Name
        end
        close column_cursor
        deallocate column_cursor
        set @cmd = @cmd + ' from ' + @t_Name + ' ' + @where + ' order by '+ str(@order)
        print @cmd
        exec (@cmd)
    end   


end
go



Hello SQL devellopers,

this is my first post using SQL-Scripts and I have to find out, which are the right tools, to present sql code here on blogger.com.

I present a small helper function which I will use to write a wrapper around the SQL Select-statement. Some academic egg-heads want to make me believe that columns have to be addressed by name, I'm going to teach them how to it by column numbers ( in my next post).

Second this is an example of my coding style. I do not use VARCHARN, [] (the damned reincarnation  of quoted identifiers) and I use the dbo. prefix at sensible places (contrary to the codegenerator in SQL-Server Management Studio ;.-).

This style has matured during one decade of SQL coding. My use of () brackets around the function parameters is nonstandard, but it works.

My style is develloped with the goal to help me convert T-SQL to PLSQL.



if object_id ('splitColumnNumberList') > 0
    drop function splitColumnNumberList
go

create function dbo.splitColumnNumberList
(
    @list varchar(8000),
    @del varchar(255) = ','
) returns @numbers table (lfd int identity(1,1),value int)
as
begin
    declare @pos    integer
    -- select CHARINDEX(',', '1,2,3')
    set @pos = CHARINDEX(@del, @list)
    while @pos > 0
        begin
            insert into  @numbers values(substring(@list, 1, @pos - 1))
            set @list = substring(@list, @pos + len(@del), 8000)
            set @pos = CHARINDEX(@del, @list)
        end

    insert into  @numbers values (@list)

    return
end

go

Hello SQL world

I created this blog, to keep SQL stuff from my main blog http://pauerschell.blogspot.com/ which is mostly about PowerShell.

I guess the focus will be on SQL-Server stored procedures.


You find my on
twitter as @bernd_k,
but if you are not interessted in PowerShell, WPF, WPK and want to focus on database stuff follow me on
twitter as @sqlsulidae.

Bernd