VB.NET With SMO!

SQL Server管理オブジェクト 略して SMOを使って、
SQLServerからイベントログ出力を行う処理を見張っているプログラムを作ってみた。
 
SMOを使うために、最低限以下のDLLをソリューションで参照するようにしてくださいまし。
(SQL Server 2008の場合 2005の場合は100を90に読み替えてください。)
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.ConnectionInfo.dll
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Management.Sdk.Sfc.dll
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.Smo.dll
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SqlServer.SqlEnum.dll
またImportも忘れずにね♪
 
ちなみに、SQLServerのTransact-SQLでイベントログ書き込みを発生させるのに使ったのは
xp_logevent (Transact-SQL)でっす。

超個人的、気分的な要因で、VB.NETになりました。
また、ただのクラスで作りましたが、Windowsサービスに入れることを視野に入れたつくりになっています。
イベントを発生させた モノの情報と、
SQLServerにキャッシュされたクエリ プランの集計パフォーマンス統計およびSQL文を
ファイルに出力するようになっています。
 
 

Imports Microsoft.SqlServer.Management.Smo
Imports Microsoft.SqlServer.Management.Common

Public Class SQLServerErrorWatcher
Const LOG_FILE As String = "C:\test.log"
Dim srv As Server
Dim file As System.IO.StreamWriter

Protected Sub OnStart(ByVal args() As String)
srv = New Server

Try
Dim serverEventHandler As ServerEventHandler = New ServerEventHandler(AddressOf MyCreateEventHandler)
Dim serverEventSet As ServerTraceEventSet = New ServerTraceEventSet
serverEventSet.Eventlog = True
srv.Events.SubscribeToEvents(serverEventSet, serverEventHandler)


file = New System.IO.StreamWriter(LOG_FILE, True, System.Text.Encoding.UTF8)
srv.Events.StartEvents()
Catch ex As Exception
OnStop()
End Try
End Sub

Protected Sub OnStop()
Try
If (srv IsNot Nothing) Then
srv.Events.StopEvents()
End If
If (file IsNot Nothing) Then
file.Close()
End If
Finally
srv = Nothing
file = Nothing
End Try
End Sub



Shared Sub Main()
Dim target As SQLServerErrorWatcher = New SQLServerErrorWatcher
target.OnStart(Nothing)

While (target.srv IsNot Nothing)
End While

target.OnStop()

End Sub


Sub MyCreateEventHandler(ByVal sender As Object, ByVal e As ServerEventArgs)
Dim str As Text.StringBuilder = New Text.StringBuilder()
Dim server As Server = sender

Dim dbid As Integer = e.Properties.Item("DatabaseID").Value

str.AppendLine("----------")
str.AppendLine(e.PostTime.ToString())
str.AppendLine("----------")
str.Append("[ApplicationName]")
If (e.Properties.Item("ApplicationName") IsNot Nothing AndAlso _
e.Properties.Item("ApplicationName").Value IsNot Nothing) Then
str.Append(e.Properties.Item("ApplicationName").Value.ToString)
End If
str.AppendLine()


str.Append("[ClientProcessID]")
If (e.Properties.Item("ClientProcessID") IsNot Nothing AndAlso _
e.Properties.Item("ClientProcessID").Value IsNot Nothing) Then
str.Append(e.Properties.Item("ClientProcessID").Value.ToString)
End If
str.AppendLine()

str.Append("[ComputerName]")
If (e.Properties.Item("ComputerName") IsNot Nothing AndAlso _
e.Properties.Item("ComputerName").Value IsNot Nothing) Then
str.Append(e.Properties.Item("ComputerName").Value.ToString)
End If
str.AppendLine()

str.Append("[DatabaseName]")
If (e.Properties.Item("DatabaseName") IsNot Nothing AndAlso _
e.Properties.Item("DatabaseName").Value IsNot Nothing) Then
str.Append(e.Properties.Item("DatabaseName").Value.ToString)
End If
str.AppendLine()

str.Append("[Error]")
If (e.Properties.Item("Error") IsNot Nothing AndAlso _
e.Properties.Item("Error").Value IsNot Nothing) Then
str.Append(e.Properties.Item("Error").Value.ToString)
End If
str.AppendLine()

str.Append("[HostName]")
If (e.Properties.Item("HostName") IsNot Nothing AndAlso _
e.Properties.Item("HostName").Value IsNot Nothing) Then
str.Append(e.Properties.Item("HostName").Value.ToString)
End If
str.AppendLine()

str.Append("[LoginName]")
If (e.Properties.Item("LoginName") IsNot Nothing AndAlso _
e.Properties.Item("LoginName").Value IsNot Nothing) Then
str.Append(e.Properties.Item("LoginName").Value.ToString)
End If
str.AppendLine()

str.Append("[RequestID]")
If (e.Properties.Item("RequestID") IsNot Nothing AndAlso _
e.Properties.Item("RequestID").Value IsNot Nothing) Then
str.Append(e.Properties.Item("RequestID").Value.ToString)
End If
str.AppendLine()

str.Append("[SessionLoginName]")
If (e.Properties.Item("SessionLoginName") IsNot Nothing AndAlso _
e.Properties.Item("SessionLoginName").Value IsNot Nothing) Then
str.Append(e.Properties.Item("SessionLoginName").Value.ToString)
End If
str.AppendLine()

str.Append("[StartTime]")
If (e.Properties.Item("StartTime") IsNot Nothing AndAlso _
e.Properties.Item("StartTime").Value IsNot Nothing) Then
str.Append(e.Properties.Item("StartTime").Value.ToString)
End If
str.AppendLine()

str.Append("[TextData]")
If (e.Properties.Item("TextData") IsNot Nothing AndAlso _
e.Properties.Item("TextData").Value IsNot Nothing) Then
str.Append(e.Properties.Item("TextData").Value.ToString)
End If
str.AppendLine()

str.Append("[TransactionID]")
If (e.Properties.Item("TransactionID") IsNot Nothing AndAlso _
e.Properties.Item("TransactionID").Value IsNot Nothing) Then
str.Append(e.Properties.Item("TransactionID").Value.ToString)
End If
str.AppendLine()

str.Append("[EventSpID]").AppendLine(e.Spid.ToString)
str.Append("[LogReuseWait]").AppendLine(server.Databases("Footprints").LogReuseWaitStatus)

Dim sql As String = "SELECT " _
+ " last_execution_time, " _
+ " execution_count, " _
+ " total_worker_time, " _
+ " last_worker_time, " _
+ " min_worker_time, " _
+ " max_worker_time, " _
+ " total_logical_reads, " _
+ " last_logical_reads, " _
+ " min_logical_reads, " _
+ " max_logical_reads, " _
+ " total_logical_writes, " _
+ " last_logical_writes, " _
+ " min_logical_writes, " _
+ " max_logical_writes, " _
+ " total_physical_reads, " _
+ " last_physical_reads, " _
+ " min_physical_reads, " _
+ " max_physical_reads, " _
+ " total_logical_writes, " _
+ " last_logical_writes, " _
+ " min_logical_writes, " _
+ " max_logical_writes, " _
+ " total_elapsed_time, " _
+ " last_elapsed_time, " _
+ " min_elapsed_time, " _
+ " max_elapsed_time, " _
+ " [text].text " _
+ "FROM " _
+ " sys.dm_exec_query_stats req " _
+ " cross apply " _
+ " sys.dm_exec_sql_text (req.plan_handle) [text] " _
+ "where dbid is null or dbid = DB_ID('Footprints') "




Dim ret As Data.DataSet = (server.Databases("master").ExecuteWithResults(sql))
Dim i As Integer = 0
Dim j As Integer = 0
For i = 0 To ret.Tables(0).Rows.Count - 1
Dim row As Data.DataRow
row = ret.Tables(0).Rows(i)
For j = 0 To ret.Tables(0).Columns.Count - 1
str.Append(ret.Tables(0).Columns(j).ColumnName)
str.Append(",")
Next
str.AppendLine()


str.Append(i)
Console.WriteLine(":")
For j = 0 To ret.Tables(0).Columns.Count - 1
str.Append("""")
str.Append(row.Item(j))
str.Append("""")
str.Append(",")
Next
file.Write(str.ToString())
file.Flush()
Next

End Sub

End Class
結果としてこんな感じの情報が出力されます。

[ApplicationName]Microsoft SQL Server Management Studio - クエリ
[ClientProcessID]7224
[ComputerName]MIMAGAWA-DELL
[DatabaseName]master
[Error]50001
[HostName]MIMAGAWA-DELL
[LoginName]MIMAGAWA-DELL\みまがわ
[RequestID]0
[SessionLoginName]MIMAGAWA-DELL\みまがわ
[StartTime]20100107135536.000983+000
[TextData]Error: 50001 Severity: 16 State: 1 message
[TransactionID]0
[EventSpID]52
[LogReuseWait]0
last_execution_time,execution_count,total_worker_time,last_worker_time,min_worker_time,max_worker_time,total_logical_reads,last_logical_reads,min_logical_reads,max_logical_reads,total_logical_writes,last_logical_writes,min_logical_writes,max_logical_writes,total_physical_reads,last_physical_reads,min_physical_reads,max_physical_reads,total_logical_writes1,last_logical_writes1,min_logical_writes1,max_logical_writes1,total_elapsed_time,last_elapsed_time,min_elapsed_time,max_elapsed_time,text,
0"2010/01/07 13:55:38","2","0","0","0","0","4","2","2","2","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","(@_msparam_0 nvarchar(4000))SELECT
dtb.name AS [Name]
FROM
master.sys.databases AS dtb
WHERE
(dtb.name=@_msparam_0)",last_execution_time,execution_count,total_worker_time,last_worker_time,min_worker_time,max_worker_time,total_logical_reads,last_logical_reads,min_logical_reads,max_logical_reads,total_logical_writes,last_logical_writes,min_logical_writes,max_logical_writes,total_physical_reads,last_physical_reads,min_physical_reads,max_physical_reads,total_logical_writes1,last_logical_writes1,min_logical_writes1,max_logical_writes1,total_elapsed_time,last_elapsed_time,min_elapsed_time,max_elapsed_time,text,1"2010/01/07 13:55:38","2","1953","0","0","1953","8","4","4","4","0","0","0","0","0","0","0","0","0","0","0","0","1953","0","0","1953","(@_msparam_0 nvarchar(4000))SELECT
dtb.compatibility_level AS [CompatibilityLevel],
dtb.name AS [DatabaseName2]
FROM
master.sys.databases AS dtb
WHERE
(dtb.name=@_msparam_0)",last_execution_time,execution_count,total_worker_time,last_worker_time,min_worker_time,max_worker_time,total_logical_reads,last_logical_reads,min_logical_reads,max_logical_reads,total_logical_writes,last_logical_writes,min_logical_writes,max_logical_writes,total_physical_reads,last_physical_reads,min_physical_reads,max_physical_reads,total_logical_writes1,last_logical_writes1,min_logical_writes1,max_logical_writes1,total_elapsed_time,last_elapsed_time,min_elapsed_time,max_elapsed_time,text,

第1回 CECパフォーマンス向上セミナー~売上アップとコスト削減は、適切なパフォーマンス管理から~

 だって(ぉぃ

 ・・・というのは冗談で、Ameba Blogを支えているシステムのパフォチューについて、

セミナーがあるそうです。

 

第1回 CECパフォーマンス向上セミナー~売上アップとコスト削減は、適切なパフォーマンス管理から~

 

Amebaは、元々多くの芸能人がオフィシャルブログを展開していますし、

Ameba Piggというアバターチャットの機能が出来てから、ユーザ数はダイブ増えたような気がします。

#そういう私もAmebaを利用している一人です。

そんな巨大なシステムのパフォチューの話なので、色々と問題解決の糸口がみえるセミナーなんじゃないでしょうか?

 

#・・・と自社イベントを宣伝してみる。

# でも、内容的に、あの巨大なAmebaのパフォチューって、マニアックそうな気がしない?

#私は関わっていないけど・・・・orz

Java Maniacs (?!) ってか、気が済むように調べてみた♪

Javaプログラムだけではないですが、ありがちなStringの+連結について、
自分なりの調査をしました。

# 使用Java Version 1.5.0_20

 

上側が私の書いたコード

下側が「コンパイルしたクラスファイルを逆コンパイルしてソースに戻したもの」

になります。

 

ソースを見比べてもらうと分かりますが、

interfaceに変数を定義するとpublic static finalが自動的に付加されるので

私がinterfaceでpublicやstaticを書かなくても、逆コンパイルしたソースにはその記述があり、

文字列連結に影響を及ぼしている事が分かるかと思います。

 

また、ただ文字列を+で付けるのと、+=で付けていくのでは動作が異なる事も見て取れると思います。

 

注目していただきたいのは、+で連結する文字列が定数だけの場合と、変数が混ざる場合のコードです。

定数だけの場合、逆コンパイルしたソースは、直に出来上がる文字列が記述されています。

 

Javaの逆コンパイルはJadというものが有名でしたが、

個人的には、javapコマンドが好きですw

#マニアックなソースコード部分以外のJavaVMが読み取る内容が見えるから~♪

# この記事では、見た目を重視し、jadにて逆コンパイルをして結果を出していますが・・・。

#jadは色々な観点から、手に入りにくくなったようで・・・探すのに苦労しましたw

 


以下、調査コード

  • UseStringBuilder
    引数で渡されたString配列データを
    StringBuilderを使って文字列連結する。
  • NotUseStringBuilder
    引数で渡されたString配列データを
    +を使って文字列連結する。
  • ChildNotUseStringBuilderFinal
    "A" + "B" + "C" + 親クラスのstatic final付きString変数値
    String変数に"A"を代入し、 "B"、"C"、親クラスのstatic final付きString変数値を +=で連結しながら変数代入していく。
  • ChildNotUseStringBuilderNotFinal
    "A" + "B" + "C" + 親クラスのstatic付きString変数値
    String変数に"A"を代入し、 "B"、"C"、親クラスのstatic付きString変数値を +=で連結しながら変数代入していく。
  • ChildNotUseStringBuilderFinalImpl
    "A" + "B" + "C" + 親インターフェースのstatic final付きString変数値
  • ChildNotUseStringBuilderNotFinalImpl
    "A" + "B" + "C" + 親インターフェースのstatic 付きString変数値
  • ChildNotUseStringBuilderNoStaticFinal
    "A" + "B" + "C" + 親クラスのfinal付きString変数値
  • ChildNotUseStringBuilderNoStaticNoFinal
    "A" + "B" + "C" + 親クラスのString変数値
  • ChildNotUseStringBuilderNoStaticFinalImpl
    "A" + "B" + "C" + 親インターフェースのfinal付きString変数値
  • ChildNotUseStringBuilderNoStaticNoFinalImpl
    "A" + "B" + "C" + 親インターフェースのString変数値


public class TestStringBuilder {

    public static void main(String[] args) {
    }
}


class UseStringBuilder {
    
    static String concat(String ... data) {
        StringBuilder buf = new StringBuilder();
        
        for(String s : data) 
            buf.append(s);
        
        return buf.toString();
    }
    
}
class NotUseStringBuilder {

    static String concat(String ... data) {
        String ret = "";
        
        for(String s : data) 
            ret += s;
        
        return ret;
    }
    
}

class ParentFinal {
    static final String data = "testA";
}

class ParentNonFinal {
    static String data = "testB";
}

class ChildNotUseStringBuilderFinal extends ParentFinal {
    static String getData() {
        return "A" + "B" + "C" + data;
    }

    static String getDataPlus() {
        String str = "A";
            str += "B" ;
            str += "C" ;
            str += data;
            return str;
    }
}

class ChildNotUseStringBuilderNotFinal extends ParentNonFinal {
    static String val = "d";

    static String getData() {
        return "A" + "B" + "C" + data;
    }
    
    static String getDataPlus() {
        String str = "A";
            str += "B" ;
            str += "C" ;
            str += data;
            return str;
    }
}

interface PInterfaceFinal {
    static final String data = "test1";
}
interface PInterfaceNonFinal {
    static String data = "test2";
}
class ChildNotUseStringBuilderFinalImpl implements PInterfaceFinal {
    static String getData() {
        return "A" + "B" + "C" + data;
    }
}

class ChildNotUseStringBuilderNotFinalImpl implements PInterfaceNonFinal {
    static String getData() {
        return "A" + "B" + "C" + data;
    }
}

class ParentNoStaticFinal {
    final String data = "NoStatic";
}
class ParentNoStaticNoFinal {
    String data = "NoStaticNoFinal";
}

class ChildNotUseStringBuilderNoStaticFinal extends ParentNoStaticFinal {
    String getData() {
        return "A" + "B" + "C" + data;
    }
}

class ChildNotUseStringBuilderNoStaticNoFinal extends ParentNoStaticNoFinal {
    String getData() {
        return "A" + "B" + "C" + data;
    }
}

interface PInterfaceNoStaticFinal {
    final String data = "aaaa";
}
interface PInterfaceNoStaticNoFinal {
    String data = "bbbb";
}

class ChildNotUseStringBuilderNoStaticFinalImpl implements PInterfaceNoStaticFinal {
    String getData() {
        return "A" + "B" + "C" + data;
    }
}

class ChildNotUseStringBuilderNoStaticNoFinalImpl implements PInterfaceNoStaticNoFinal {
    String getData() {
        return "A" + "B" + "C" + data;
    }
}



public class TestStringBuilder
{

    public TestStringBuilder()
    {
    }

    public static void main(String args1[])
    {
    }
}
class UseStringBuilder
{

    UseStringBuilder()
    {
    }

    static transient String concat(String data[])
    {
        StringBuilder buf = new StringBuilder();
        String as[] = data;
        int i = 0;
        for(int j = as.length; i < j; i++)
        {
            String s = as[i];
            buf.append(s);
        }

        return buf.toString();
    }
}
class NotUseStringBuilder
{

    NotUseStringBuilder()
    {
    }

    static transient String concat(String data[])
    {
        String ret = "";
        String as[] = data;
        int i = 0;
        for(int j = as.length; i < j; i++)
        {
            String s = as[i];
            ret = (new StringBuilder(String.valueOf(ret))).append(s).toString();
        }

        return ret;
    }
}
class ParentFinal
{

    ParentFinal()
    {
    }

    static final String data = "testA";
}
class ParentNonFinal
{

    ParentNonFinal()
    {
    }

    static String data = "testB";

}
class ChildNotUseStringBuilderFinal extends ParentFinal
{

    ChildNotUseStringBuilderFinal()
    {
    }

    static String getData()
    {
        return "ABCtestA";
    }

    static String getDataPlus()
    {
        String str = "A";
        str = (new StringBuilder(String.valueOf(str))).append("B").toString();
        str = (new StringBuilder(String.valueOf(str))).append("C").toString();
        str = (new StringBuilder(String.valueOf(str))).append("testA").toString();
        return str;
    }
}
class ChildNotUseStringBuilderNotFinal extends ParentNonFinal
{

    ChildNotUseStringBuilderNotFinal()
    {
    }

    static String getData()
    {
        return (new StringBuilder("ABC")).append(data).toString();
    }

    static String getDataPlus()
    {
        String str = "A";
        str = (new StringBuilder(String.valueOf(str))).append("B").toString();
        str = (new StringBuilder(String.valueOf(str))).append("C").toString();
        str = (new StringBuilder(String.valueOf(str))).append(data).toString();
        return str;
    }

    static String val = "d";

}
interface PInterfaceFinal
{

    public static final String data = "test1";
}
interface PInterfaceNonFinal
{

    public static final String data = "test2";
}
class ChildNotUseStringBuilderFinalImpl
    implements PInterfaceFinal
{

    ChildNotUseStringBuilderFinalImpl()
    {
    }

    static String getData()
    {
        return "ABCtest1";
    }
}
class ChildNotUseStringBuilderNotFinalImpl
    implements PInterfaceNonFinal
{

    ChildNotUseStringBuilderNotFinalImpl()
    {
    }

    static String getData()
    {
        return "ABCtest2";
    }
}
class ParentNoStaticFinal
{

    ParentNoStaticFinal()
    {
    }

    final String data = "NoStatic";
}
class ParentNoStaticNoFinal
{

    ParentNoStaticNoFinal()
    {
        data = "NoStaticNoFinal";
    }

    String data;
}
class ChildNotUseStringBuilderNoStaticFinal extends ParentNoStaticFinal
{

    ChildNotUseStringBuilderNoStaticFinal()
    {
    }

    String getData()
    {
        return "ABCNoStatic";
    }
}
class ChildNotUseStringBuilderNoStaticNoFinal extends ParentNoStaticNoFinal
{

    ChildNotUseStringBuilderNoStaticNoFinal()
    {
    }

    String getData()
    {
        return (new StringBuilder("ABC")).append(data).toString();
    }
}
interface PInterfaceNoStaticFinal
{

    public static final String data = "aaaa";
}
interface PInterfaceNoStaticNoFinal
{

    public static final String data = "bbbb";
}
class ChildNotUseStringBuilderNoStaticFinalImpl
    implements PInterfaceNoStaticFinal
{

    ChildNotUseStringBuilderNoStaticFinalImpl()
    {
    }

    String getData()
    {
        return "ABCaaaa";
    }
}
class ChildNotUseStringBuilderNoStaticNoFinalImpl
    implements PInterfaceNoStaticNoFinal
{

    ChildNotUseStringBuilderNoStaticNoFinalImpl()
    {
    }

    String getData()
    {
        return "ABCbbbb";
    }
}

Java版だぜ!【 ↑の さんのBlog:VB勉強記録:2】

↑のさんのBLOGにありました
名前をいれると「こんにちは」を付加してラベルに出力するものを
JavaのSwing版で作ってみました。

比較してみると面白いかもしれません。
# 元ネタ⇒VB勉強記録:2@↑の さんのBlog



import java.awt.Frame;
import javax.swing.JDialog;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JLabel;

public class Dialog extends JDialog {

    private static final long serialVersionUID = 1L;

    private JTextField jTextField = null;

    private JButton jButton = null;

    private JLabel jLabel = null;

    
    public static void main(String[] args) {
        Dialog d = new Dialog(null);
        d.setVisible(true);
        
        return ;
    }
    
    /**
     * @param owner
     */
    public Dialog(Frame owner) {
        super(owner);
        initialize();
    }

    /**
     * This method initializes this
     * 
     * @return void
     */
    private void initialize() {
        this.setSize(220, 100);
        
        this.add(getJTextField());
        this.add(getJButton());
        this.add(getJLabel());
        jTextField.setBounds(0, 0, 100, 25);
        jButton.setBounds(110, 0, 100, 25);
        jLabel.setBounds(0,50, 100, 25);
        this.setResizable(false);

        this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    }

    private JLabel getJLabel() {
        if( jLabel == null ) {
            jLabel = new JLabel();
        }
        return jLabel;
    }
    
    /**
     * This method initializes jTextField   
     *  
     * @return javax.swing.JTextField   
     */
    private JTextField getJTextField() {
        if (jTextField == null) {
            jTextField = new JTextField();
        }
        return jTextField;
    }

    /**
     * This method initializes jButton  
     *  
     * @return javax.swing.JButton  
     */
    private JButton getJButton() {
        if (jButton == null) {
            jButton = new JButton();
            jButton.setText("Click Me!");
            
            jButton.addActionListener(new java.awt.event.ActionListener() {
                
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    if( jTextField.getText().length() > 0) 
                        jLabel.setText(jTextField.getText() + "さん、こんにちは!");
                    else
                        jLabel.setText("入力してね♪");
                }
            });
        }
        return jButton;
    }

}
実行開始直後の状態
実行直後

テキストボックスに入力して、Click!
名前入力してClick!

テキストボックスを空にして、Click!
なにも入力せずClick!

SQL Serverのメルマガを配信します♪

CLUB INSIGHTにて

SQL Serverのメルマガを配信することになりました♪

もちろん、メインで書いているのは私です♪

#お陰で、オンライン活動が出来ない罠(www


メルマガに熱を入れていますので
ぜひ、登録していただけたら幸いです!!

初回配信は今月中で~す♪

 

俺的Marge文検証

SQL Server 2008からやっとMERGE文が出たので、
俺的検証!


/*
drop type testTableType;
CREATE TYPE testTableType
    AS TABLE ( a int, b varchar(100) );
*/
/*
*/
Declare @t1v int;
Declare @t2v int;

set @t1v = 1;
set @t2v = 10;


set statistics time off;
truncate table t1;
truncate table t2;

insert into t1 select num, 'A' + cast(num as varchar) from GENERATE_SERIES(1,20000,@t1v);
insert into t2 select num, 'B' + cast(num as varchar) from GENERATE_SERIES(1,20000,@t2v);

declare @testTable testTableType;

set statistics time on;
insert into @testTable 
    select 
    case when t1.a Is null then t2.a else t1.a end as a, 
    case when t2.b is null then t1.b else t2.b end as b
    from t1 full join t2 on t1.a = t2.a 
truncate table t1;
insert into t1 select * from @testTable;
set statistics time off;



set statistics time off;
truncate table t1;
truncate table t2;

insert into t1 select num, 'A' + cast(num as varchar) from GENERATE_SERIES(1,20000,@t1v);
insert into t2 select num, 'B' + cast(num as varchar) from GENERATE_SERIES(1,20000,@t2v);

set statistics time on;
MERGE INTO t1
USING t2
ON t1.a = t2.a
WHEN MATCHED THEN
UPDATE SET t1.b = t2.b
WHEN NOT MATCHED THEN
INSERT VALUES ( t2.a, t2.b );
set statistics time off;



上記がSQLServer2005までで同機能を持ったSQLをつくって見たものと

MERGE文に書き換えたものの2パターンになります。



以下 実行結果。




(20000 行処理されました)

(1 行処理されました)

(2000 行処理されました)

(1 行処理されました)

(20000 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 31 ミリ秒、経過時間 = 70 ミリ秒。

 SQL Server 実行時間: 
、CPU 時間 = 0 ミリ秒、経過時間 = 0 ミリ秒。

(20000 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 63 ミリ秒、経過時間 = 86 ミリ秒。

(20000 行処理されました)

(1 行処理されました)

(2000 行処理されました)

(1 行処理されました)

(2000 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 31 ミリ秒、経過時間 = 75 ミリ秒。



CPU 時間 = 31 ミリ秒、経過時間 = 70 ミリ秒。
CPU 時間 = 0 ミリ秒、経過時間 = 0 ミリ秒。
CPU 時間 = 63 ミリ秒、経過時間 = 86 ミリ秒。
-----------------------------------------
CPU 時間 = 94 ミリ秒、経過時間 = 156 ミリ秒。←上記3つ合算

CPU 時間 = 31 ミリ秒、経過時間 = 69 ミリ秒。←MERGEでの時間

・・・えっっと・・・・・・FULL JOINの方がCPU食うのね。

次に

set @t1v = 1;
set @t2v = 1000;
に書き換えて実行。




(20000 行処理されました)

(1 行処理されました)

(20 行処理されました)

(1 行処理されました)

(20000 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 15 ミリ秒、経過時間 = 71 ミリ秒。

 SQL Server 実行時間: 
、CPU 時間 = 0 ミリ秒、経過時間 = 0 ミリ秒。

(20000 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 79 ミリ秒、経過時間 = 75 ミリ秒。

(20000 行処理されました)

(1 行処理されました)

(20 行処理されました)

(1 行処理されました)

(20 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 0 ミリ秒、経過時間 = 53 ミリ秒。


CPU 時間 = 15 ミリ秒、経過時間 = 71 ミリ秒。
CPU 時間 = 0 ミリ秒、経過時間 = 0 ミリ秒。
CPU 時間 = 79 ミリ秒、経過時間 = 75 ミリ秒。
-----------------------------------------
CPU 時間 = 94 ミリ秒、経過時間 = 145 ミリ秒。

CPU 時間 = 0 ミリ秒、経過時間 = 53 ミリ秒。

・・・・まぁ、どんどん大差が(--;



次に

set @t1v = 1000;
set @t2v = 1;
に書き換えて実行。



(20 行処理されました)

(1 行処理されました)

(20000 行処理されました)

(1 行処理されました)

(20000 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 15 ミリ秒、経過時間 = 66 ミリ秒。

 SQL Server 実行時間: 
、CPU 時間 = 0 ミリ秒、経過時間 = 0 ミリ秒。

(20000 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 78 ミリ秒、経過時間 = 75 ミリ秒。

(20 行処理されました)

(1 行処理されました)

(20000 行処理されました)

(1 行処理されました)

(20000 行処理されました)

(1 行処理されました)

 SQL Server 実行時間: 
、CPU 時間 = 110 ミリ秒、経過時間 = 155 ミリ秒。

CPU 時間 = 15 ミリ秒、経過時間 = 66 ミリ秒。
CPU 時間 = 0 ミリ秒、経過時間 = 0 ミリ秒。
CPU 時間 = 78 ミリ秒、経過時間 = 75 ミリ秒。
-----------------------------------------
CPU 時間 = 93 ミリ秒、経過時間 = 141 ミリ秒。

CPU 時間 = 110 ミリ秒、経過時間 = 155 ミリ秒。


・・・なるほど、MERGEしてINSERT対象になるデータが多い時は
MERGEの方がCPUも時間も消費するのかも。


取り合えずOKそうな対応発見 ~ --- AIX5.3上におけるjava.nio.channels.Selectorの挙動がおかしい件。

AIX5.3上におけるjava.nio.channels.Selectorの挙動がおかしい件のその後です。

 色々試行錯誤してみたものの、

やはり通信用スレッドと何かがロックがかかっているようなので、

通信スレッドに対してThread.yieldをかけたところ、遅延が発生しなくなりました。

 

ちなみに、Thread.yieldをしない状態で

Java6@AIX5.3 で動作しても、遅延は発生していました。 

 

とりあえず、このミニマムコードではなく、

本当の製品コード(←こいつがまぁた複雑怪奇なロジック)でも試して見たのですが、

Thread.yieldいれた後に遅延は見受けられなかったので

今のところの対応として見えているのは、これですかね。


========= Server側プログラム==========


import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;


public class Server {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) {
        try {
            ServerConnectionManagement server =  new ServerConnectionManagement(Integer.parseInt(args[0]));
            Thread t = new Thread(server);
            t.start();
            
            InputStreamReader fp = new InputStreamReader(System.in);
            StringBuilder buf = new StringBuilder();

            while(true) {
                int i = fp.read();
                if (i == '\n')  {
                    String str = new String(buf.toString().getBytes());
                    buf.delete(0, buf.length());
                    server.addWriteData(str);
                } else if( i != '\r') {
                    buf.append((char)i);
                }
        }

            
        } catch (Exception e) {
            // TODO 自動生成された catch ブロック
            e.printStackTrace();
        }
    }
}

class ServerConnectionManagement implements Runnable {
    private Selector serverSelector = null;
    private ServerSocketChannel serverChannel= null;
    private static final int BUF_SIZE = 1024;
    
    private ArrayList writeList = new ArrayList();
    private SelectionKey sk = null;

    public ServerConnectionManagement(int port) throws IOException {
        
        serverSelector = Selector.open();
        serverChannel = ServerSocketChannel.open(); 
        serverChannel.socket().bind(new InetSocketAddress(port));
        serverChannel.configureBlocking(false);
        SelectionKey addedKey = serverChannel.register(serverSelector, SelectionKey.OP_ACCEPT);
        addedKey.interestOps(SelectionKey.OP_ACCEPT);
    }
    
    public void run() {
        try {
            while(true) {
                Thread.yield();
                while(serverSelector.select(100) > 0) {
                    System.out.println("In Second While");
                    Set keyList = serverSelector.selectedKeys();
                    for (Iterator it = keyList.iterator(); it.hasNext(); ) {
                        SelectionKey selectionKey = it.next();
                        it.remove();
                        
                        if(selectionKey.isAcceptable()) {
                            SocketChannel ssc = serverChannel.accept();
                            if( ssc == null ) {
                                continue ;
                            }
                            ssc.configureBlocking(false);
                            SelectionKey addedKey = ssc.register(serverSelector, SelectionKey.OP_READ);
                            addedKey.interestOps(SelectionKey.OP_READ);
                            sk = addedKey;
                        }else if( selectionKey.isReadable()) {
                            SocketChannel ssc = 
                                (SocketChannel)selectionKey.channel();
                            read(ssc);
                            
                        }else if( selectionKey.isWritable()) {
                            if( writeList.size() > 0 ) {
                                SocketChannel ssc = 
                                    (SocketChannel)selectionKey.channel();
                                String data = writeList.get(0);
                                writeList.remove(0);
                                write(ssc, data);
                                if(writeList.size() > 0 ) 
                                    selectionKey.interestOps(SelectionKey.OP_WRITE);
                                else
                                    selectionKey.interestOps(SelectionKey.OP_READ);

                            }
                        }
                    }
                }
            }
        } catch(Exception ex) {
            ex.printStackTrace();
        } finally {
            
        }
    }
    
    private void read(SocketChannel in) throws IOException {
        byte[] data = new byte[BUF_SIZE];
        int readCount = in.read(ByteBuffer.wrap(data));
        String str = String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN read data [%2$s]", new Date(), new String(data, 0 , readCount));
        System.out.println(str);
    }
    private void write(SocketChannel in, String data) throws IOException {
        in.write(ByteBuffer.wrap(data.getBytes()));
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN write data [%2$s]", new Date(), data));
    }
    public void addWriteData(String data) throws IOException {
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN addWriteData data [%2$s]", new Date(), data));
        writeList.add(data);
        sk.interestOps(SelectionKey.OP_WRITE);
    }

}
========= Client側プログラム==========

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;


public class Client {


    /**
     * @param args
     */
    public static void main(String[] args) {
        
        ClientConnectionManagement client;
        try {
            client = new ClientConnectionManagement(Integer.parseInt(args[0]));
            Thread t = new Thread(client);
            
            client.addWriteData("AAA");
            client.addWriteData("BBB");
            t.start();
            
            
            InputStreamReader fp = new InputStreamReader(System.in);
            StringBuilder buf = new StringBuilder();
            
            while(true) {
                    int i = fp.read();
                    if (i == '\n')  {
                        String str = new String(buf.toString().getBytes());
                        buf.delete(0, buf.length());
                        client.addWriteData(str);
                    } else if( i != '\r') {
                        buf.append((char)i);
                    }
            }
            
        } catch (Exception e) {
            // TODO 自動生成された catch ブロック
            e.printStackTrace();
        }
        
    }
}

class ClientConnectionManagement implements Runnable {
    
    private static final int BUF_SIZE = 1024;
    private Selector clientSelector = null;
    private SocketChannel socketChannel = null;
    private ArrayList writeList = new ArrayList();

    public ClientConnectionManagement(int port) throws IOException {
        clientSelector = Selector.open();
        socketChannel = SocketChannel.open(new InetSocketAddress(port)); 
        socketChannel.configureBlocking(false);
        socketChannel.register(clientSelector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ);
    }

    public void run() {
        try {
            while(true) {
                Thread.yield();
                while(clientSelector.select(100) > 0 ) {
                    System.out.println("In Second While");
                    Set keyList = clientSelector.selectedKeys();
                    
                    for (Iterator it = keyList.iterator(); it.hasNext(); ) {
                        SelectionKey selectionKey = it.next();
                        it.remove();
                        if( selectionKey.isWritable()) {
                            if( writeList.size() > 0) {
                                SocketChannel channel = (SocketChannel)selectionKey.channel();
                                String data = writeList.get(0);
                                writeList.remove(0);
                                write(channel, data);
                                if(writeList.size() > 0 ) 
                                    socketChannel.register(clientSelector, SelectionKey.OP_WRITE);
                                else
                                    socketChannel.register(clientSelector, SelectionKey.OP_READ);
                            }
                        } else if(selectionKey.isReadable()) {
                            SocketChannel channel = (SocketChannel)selectionKey.channel();
                            read(channel);
                            socketChannel.register(clientSelector, SelectionKey.OP_READ);
                        }
                    }
                }
            }
        } catch(Exception ex) {
            ex.printStackTrace();
        } finally {
            
        }
    }
    private void read(SocketChannel in) throws IOException {
        byte[] data = new byte[BUF_SIZE];
        int readCount = in.read(ByteBuffer.wrap(data));
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN read data [%2$s]", new Date(), new String(data, 0 , readCount)));
        
    }
    private void write(SocketChannel in, String data) throws IOException {
        in.write(ByteBuffer.wrap(data.getBytes()));
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN write data [%2$s]", new Date(), data));
    }
    public void addWriteData(String data) throws IOException {
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN addWriteData data [%2$s]", new Date(), data));
        writeList.add(data);
        socketChannel.register(clientSelector, SelectionKey.OP_WRITE);
    }
}

AIX5.3上におけるjava.nio.channels.Selectorの挙動がおかしい件

お久しぶりです。夏椰です。

いま、お仕事でJava5プログラムの通信部分を作成しております。

クライアントとサーバがお互いに、お互いのトリガでデータの送受信を行うプログラムです。 

 

下記プログラムコードは問題把握のために作ったミニマムプログラム君ですが 

どんな問題が起きたかと言いますと・・・・。

このプログラム、Eclipse3.2 @ WindowsXP SP3 / Linux では何の問題もなく動きます。

しかぁし!!!

AIX5.3で動かすと、送受信でとっても遅延が出るんです

しかも、遅延時間もまちまち!! 

デバッグすると、どうもjava.nio.channels.Selectorでちゃんとキーが取れていないようで・・・。

解決策は、いま模索中・・・・・

何か情報お持ちでしたら、教えてください。

ちなみに、Selector#wakeup かけても遅延は起きる・・・。

今の開発環境では、まぁ、遅れて10秒近くですが、

VirtualなAIX上だともっと遅れるらしい・・・。


========= Server側プログラム==========


import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;


public class Server {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) {
        try {
            ServerConnectionManagement server =  new ServerConnectionManagement(Integer.parseInt(args[0]));
            Thread t = new Thread(server);
            t.start();
            
            InputStreamReader fp = new InputStreamReader(System.in);
            StringBuilder buf = new StringBuilder();

            while(true) {
                int i = fp.read();
                if (i == '\n')  {
                    String str = new String(buf.toString().getBytes());
                    buf.delete(0, buf.length());
                    server.addWriteData(str);
                } else if( i != '\r') {
                    buf.append((char)i);
                }
        }

            
        } catch (Exception e) {
            // TODO 自動生成された catch ブロック
            e.printStackTrace();
        }
    }
}

class ServerConnectionManagement implements Runnable {
    private Selector serverSelector = null;
    private ServerSocketChannel serverChannel= null;
    private static final int BUF_SIZE = 1024;
    
    private ArrayList writeList = new ArrayList();
    private SelectionKey sk = null;
    

    public ServerConnectionManagement(int port) throws IOException {
        
        serverSelector = Selector.open();
        serverChannel = ServerSocketChannel.open(); 
        serverChannel.socket().bind(new InetSocketAddress(port));
        serverChannel.configureBlocking(false);
        SelectionKey addedKey = serverChannel.register(serverSelector, SelectionKey.OP_ACCEPT);
        addedKey.interestOps(SelectionKey.OP_ACCEPT);
    }
    
    public void run() {
        try {
            while(true) {
                while(serverSelector.select(100) > 0) {
                    Set keyList = serverSelector.selectedKeys();
                    for (Iterator it = keyList.iterator(); it.hasNext(); ) {
                        SelectionKey selectionKey = it.next();
                        it.remove();
                        
                        if(selectionKey.isAcceptable()) {
                            SocketChannel ssc = serverChannel.accept();
                            if( ssc == null ) {
                                continue ;
                            }
                            ssc.configureBlocking(false);
                            SelectionKey addedKey = ssc.register(serverSelector, SelectionKey.OP_READ);
                            addedKey.interestOps(SelectionKey.OP_READ);
                            sk = addedKey;
                        }else if( selectionKey.isReadable()) {
                            SocketChannel ssc = 
                                (SocketChannel)selectionKey.channel();
                            read(ssc);
                            
                        }else if( selectionKey.isWritable()) {
                            if( writeList.size() > 0 ) {
                                SocketChannel ssc = 
                                    (SocketChannel)selectionKey.channel();
                                String data = writeList.get(0);
                                writeList.remove(0);
                                write(ssc, data);
                                if(writeList.size() > 0 ) 
                                    selectionKey.interestOps(SelectionKey.OP_WRITE);
                                else
                                    selectionKey.interestOps(SelectionKey.OP_READ);

                            }
                        }
                    }
                }
            }
        } catch(Exception ex) {
            ex.printStackTrace();
        } finally {
            
        }
    }
    
    private void read(SocketChannel in) throws IOException {
        byte[] data = new byte[BUF_SIZE];
        int readCount = in.read(ByteBuffer.wrap(data));
        String str = String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN read data [%2$s]", new Date(), new String(data, 0 , readCount));
        System.out.println(str);
    }
    private void write(SocketChannel in, String data) throws IOException {
        in.write(ByteBuffer.wrap(data.getBytes()));
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN write data [%2$s]", new Date(), data));
    }
    public void addWriteData(String data) throws IOException {
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN addWriteData data [%2$s]", new Date(), data));
        writeList.add(data);
        sk.interestOps(SelectionKey.OP_WRITE);
    }

}
========= Client側プログラム==========


import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;


public class Client {


    /**
     * @param args
     */
    public static void main(String[] args) {
        
        ClientConnectionManagement client;
        try {
            client = new ClientConnectionManagement(Integer.parseInt(args[0]));
            Thread t = new Thread(client);
            
            client.addWriteData("AAA");
            client.addWriteData("BBB");
            t.start();
            
            
            InputStreamReader fp = new InputStreamReader(System.in);
            StringBuilder buf = new StringBuilder();
            
            while(true) {
                    int i = fp.read();
                    if (i == '\n')  {
                        String str = new String(buf.toString().getBytes());
                        buf.delete(0, buf.length());
                        client.addWriteData(str);
                    } else if( i != '\r') {
                        buf.append((char)i);
                    }
            }
            
        } catch (Exception e) {
            // TODO 自動生成された catch ブロック
            e.printStackTrace();
        }
        
    }
}

class ClientConnectionManagement implements Runnable {
    
    private static final int BUF_SIZE = 1024;
    private Selector clientSelector = null;
    private SocketChannel socketChannel = null;
    private ArrayList writeList = new ArrayList();

    public ClientConnectionManagement(int port) throws IOException {
        clientSelector = Selector.open();
        socketChannel = SocketChannel.open(new InetSocketAddress(port)); 
        socketChannel.configureBlocking(false);
        socketChannel.register(clientSelector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ);
    }

    public void run() {
        try {
            while(true) {
                while(clientSelector.select(100) > 0 ) {
                    Set keyList = clientSelector.selectedKeys();
                    
                    for (Iterator it = keyList.iterator(); it.hasNext(); ) {
                        SelectionKey selectionKey = it.next();
                        it.remove();
                        if( selectionKey.isWritable()) {
                            if( writeList.size() > 0) {
                                SocketChannel channel = (SocketChannel)selectionKey.channel();
                                String data = writeList.get(0);
                                writeList.remove(0);
                                write(channel, data);
                                if(writeList.size() > 0 ) 
                                    socketChannel.register(clientSelector, SelectionKey.OP_WRITE);
                                else
                                    socketChannel.register(clientSelector, SelectionKey.OP_READ);
                            }
                        } else if(selectionKey.isReadable()) {
                            SocketChannel channel = (SocketChannel)selectionKey.channel();
                            read(channel);
                            socketChannel.register(clientSelector, SelectionKey.OP_READ);
                        }
                    }
                }
            }
        } catch(Exception ex) {
            ex.printStackTrace();
        } finally {
            
        }
    }
    private void read(SocketChannel in) throws IOException {
        byte[] data = new byte[BUF_SIZE];
        int readCount = in.read(ByteBuffer.wrap(data));
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN read data [%2$s]", new Date(), new String(data, 0 , readCount)));
        
    }
    private void write(SocketChannel in, String data) throws IOException {
        in.write(ByteBuffer.wrap(data.getBytes()));
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN write data [%2$s]", new Date(), data));
    }
    public void addWriteData(String data) throws ClosedChannelException {
        System.out.println(String.format("%1$tH:%1$tM:%1$tS.%1$tL.%1$tN addWriteData data [%2$s]", new Date(), data));
        writeList.add(data);
        socketChannel.register(clientSelector, SelectionKey.OP_WRITE);
    }
}

自分を大切にしてください。

ども、お久しゅうございます。

転職してから、仕事でいろいろあったってわけではなく、

私がなんと、ライトワーカーだとわかったことで、

いろいろ鍛錬をしていたので、更新していませんでした。

 

ちょっと、リーディング=神託をお伝えしたくて、

今回BLOGを書きます。

 

今の時期、みなさんお忙しいとは思いますが、

どうかご自愛してください。

そして、食べるもの、飲むものに感謝をしながら

自分の体に残るものとして、

気を払い、エネルギーを蓄えてください。

 

きっと、そのエネルギーを使って作ったものは

あなたの糧になるでしょう。

 

 

はい、変人ですみませんっっっ(w

#まぁ、これも鍛錬の一環なんで・・・・

datetimeoffsetとdatetime2の優先順位

http://blogs.wankuma.com/kaya/archive/2008/10/14/158788.aspxでも書いた内容をこちらにも・・・。


SQLServer2008から登場したdatetimeoffsetとdatetime2はdatetimeよりも
優先順位が高いはずなんですが、
datetimeoffsetとdatetimeを加算→datetime型の結果
datetime2とdatetimeを加算→datetime型の結果

となってしまいました・・・。

意識して使用する事を考えていた方はお気をつけくださいまし。

table値関数「GetProp」を作成してみました。

以前、~ SELECTの基礎1 ~で、最後に出てきた
SQL_VARIANT_PROPERTY (Transact-SQL)を、
いちいち書くのが面倒なので、テーブル値関数を作成してみました。

関数名は「GetProp」という名前にして、SQL_VARIANT_PROPERTYで取得できる項目すべてが列になっています。

関数を作成するSQLは以下のとおりです。

CREATE FUNCTION [GetProp](@col AS SQL_VARIANT)
RETURNS 
    @ret TABLE(
        [BaseType] VARCHAR(max),
        [Precision] INT,
        [Scale] INT,
        [TotalBytes] INT,
        [Collation] VARCHAR(max),
        [MaxLength] INT
    )
BEGIN
    INSERT INTO @ret 
    SELECT
    cast(SQL_VARIANT_PROPERTY (@col,'BaseType') AS VARCHAR(max)) AS 'BaseType',
    cast(SQL_VARIANT_PROPERTY (@col,'Precision') AS INT) AS 'Precision',
    cast(SQL_VARIANT_PROPERTY (@col,'Scale') AS int) AS 'Scale',
    cast(SQL_VARIANT_PROPERTY (@col,'TotalBytes') AS INT) AS 'TotalBytes',
    cast(SQL_VARIANT_PROPERTY (@col,'Collation') AS VARCHAR(max)) AS 'Collation',
    cast(SQL_VARIANT_PROPERTY (@col,'MaxLength') AS INT) AS 'MaxLength';
    RETURN;
END ;


これを実行するサンプルは以下のとおりです。

SELECT
  * 
FROM
GetProp(
1000000000000000000000000000000000000.5
);

実行結果は以下のようになります。
BaseType Precision Scale TotalBytes Collation MaxLength
numeric 38 1 21 NULL 17

テーブルの列を検査するにはAPPLY の使用で行います。


SELECT *
FROM 
    tb1 cross apply dbo.GetProp(value2);
    



実行対象にしたtb1の内容は以下のとおりです。
id value value2
1 test NULL
2 test2 val2
3 test2 val2


これにGetPropでCROSS APPLYをした結果は以下のようになります。
id value value2 BaseType Precision Scale TotalBytes Collation MaxLength
1 test NULL NULL NULL NULL NULL NULL NULL
2 test2 val2 nvarchar 0 0 16 Japanese_CI_AS 100
3 test2 val2 nvarchar 0 0 16 Japanese_CI_AS 100

 

こんな感じで、手軽に型判別や照合順序、サイズなどを調べることが出来るようになるので、
何かのお役に立てれば幸いです。

転職しました。

お久しゅうございます。

10月から転職しまして、今はInsight Technology, Inc.に勤めています。

これでお仕事と趣味が一致しました(爆

いろいろ画策していますし、会社からのBLOG更新も了解を得たので、
ようやくこちらに書かせていただきました。

これから、もっとDBMSについて理解を深めて、皆様のお役に立てる情報が出せるように頑張りますので、
ご愛顧のほどよろしくお願いします。

ぬぉう、久々になってしまった。

 お久しゅうございます。

 

カメラマン夏椰です♪

 

現在 わんくま同盟の勉強会に向けたプログラム作成&パワポ作成に追われております~。

.NETの中にSyncFrameworkというものが追加され、

データ同期のプログラムを実装するための基盤みたい機能が提供されました。

 

10月の勉強会では、C#にてSyncFrameworkを使用したプログラム2種をお送りする予定です。

SyncFrameworkにご興味のある方はぜひ、勉強会へいらして下さい。

また、これなくても後日、作成したプログラムなどはすべて公開するので

お楽しみに~♪

 

初めてまともにC#でプログラムしたよ~~ん♪

 

って,

こっちでわんくま同盟の宣伝しちゃった。

 

 

そうそう、来月から私はシステム屋さんからソフト屋さんへ鞍替えします♪

DBのパフォチューや監査をするソフト作成を行っている会社に転職するとです♪

SQL Server 2008を使用する際にきをつけなければいけないFireWallの設定

SQLServer2008を使用する際に、あらかじめファイアウォールの設定が必要になると思われますので、
リンクを張っておきます。
参考にして、適切にポートを開けてください。

SQL Server 2008 オンライン ブック SQL Server のアクセスを許可するための Windows ファイアウォールの構成
最新投稿をさらに見る 次ページ »