C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: SQLServerの検索結果を正しく出したい


(過去ログ 122 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■72887 / inTopicNo.1)  SQLServerの検索結果を正しく出したい
  
□投稿者/ mo (4回)-(2014/07/30(Wed) 17:00:32)

分類:[VB.NET/VB2005 以降] 

使用ソフト
Microsoft Visual Studio 2010
SQLserver2008

参考にしたサイト
http://jeanne.wankuma.com/tips/vb.net/sqlserver/executereader.html

VBに設置したTextbox1に担当者のコードを入力して、別のコントロールをアクティブにした際にSQLserverに保存されている「担当者一覧」というテーブルからコードが一致する場合はLabel1にその担当者名を、一致しなかった場合はエラーのMessageboxを出現させて再度入力をさせるコードをとあるサイトのコードを見ながら作っています。
実際に担当者名をLabel1に表示させる事は出来るのですが、名前が二つ表示する様になっています(担当者名が「日産」ならLabel1には「日産日産」と表示されます。)
SELECTの「担当者名」を「*」に変えてから試してみると、「1000日産」とLabel1に表示されました。
担当者名を「日産」と、一つだけ表示させたいのですがどうすれば良いのでしょか?


SQLserverの担当者一覧の中身
担当者コード 担当者名
1000 日産
2000 トヨタ
3000 三菱


Private Sub TextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
        Try
            Using con As New SqlConnection
                con.ConnectionString = "Data Source=PC名;Initial Catalog=テーブル名;Integrated Security=True"

                con.Open()

                Dim HC As System.Data.SqlClient.SqlCommand = con.CreateCommand()
                HC.CommandText = "SELECT 担当者名 FROM 担当者一覧 WHERE (担当者コード LIKE '" & TextBox1.Text & "')"
                Dim CR As System.Data.SqlClient.SqlDataReader = HC.ExecuteReader()

                HC.Dispose()

                Dim stP As String = String.Empty
                While (CR.Read())
                    stP &= CR(0).ToString()
                    stP &= CR("担当者名").ToString()
                    stP &= System.Environment.NewLine
                End While

                CR.Close()

                If stP = "" Then
                    MessageBox.Show("再度入力して下さい")
                    TextBox1.Select()
                Else
                    Label1.Text = stP
                End If

            End Using
        Catch ex As Exception
           
        End Try
    End Sub

引用返信 編集キー/
■72889 / inTopicNo.2)  Re[1]: SQLServerの検索結果を正しく出したい
□投稿者/ Hongliang (214回)-(2014/07/30(Wed) 17:09:29)
> While (CR.Read())
> stP &= CR(0).ToString()
> stP &= CR("担当者名").ToString()
> stP &= System.Environment.NewLine
> End While

なぜCR(0)とCR("担当者名")をそれぞれstPに追加しているのでしょうか?
引用返信 編集キー/
■72897 / inTopicNo.3)  Re[2]: SQLServerの検索結果を正しく出したい
□投稿者/ mo (6回)-(2014/07/31(Thu) 09:54:39)
2014/07/31(Thu) 09:57:40 編集(投稿者)

No72889 (Hongliang さん) に返信
>>While (CR.Read())
>> stP &= CR(0).ToString()
>> stP &= CR("担当者名").ToString()
>> stP &= System.Environment.NewLine
>>End While
>
> なぜCR(0)とCR("担当者名")をそれぞれstPに追加しているのでしょうか?

サイトに書かれていたコードを理解せずにそのままコピーして使用していました。

「stP &= CR(0).ToString()」と「stP &= System.Environment.NewLine」の二か所を削除する事で欲しい動きになりました。

Hongliangさん、Comoboboxの件に続いて有難うございます。

このコードを応用する事で、IDとパスワードが必要なログインコードなどを作る事は可能でしょうか?

解決済み
引用返信 編集キー/
■72899 / inTopicNo.4)  Re[3]: SQLServerの検索結果を正しく出したい
□投稿者/ PANG2 (39回)-(2014/07/31(Thu) 11:02:21)
> 「stP &= CR(0).ToString()」と「stP &= System.Environment.NewLine」の二か所を削除する事で欲しい動きになりました。

テキストボックスに % を入力すると、どうなりますか?
期待している動きですか?

引用返信 編集キー/
■72900 / inTopicNo.5)  Re[3]: SQLServerの検索結果を正しく出したい
□投稿者/ Hongliang (215回)-(2014/07/31(Thu) 11:02:47)
> このコードを応用する事で、IDとパスワードが必要なログインコードなどを作る事は可能でしょうか?
どこにログインするのか、どんなログイン情報が必要なのか、どういう手段でログインするのか、利用許諾等で認められた行為なのか、そういうのをすっ飛ばして可能かどうか論じることは不可能です。
引用返信 編集キー/
■72964 / inTopicNo.6)  Re[4]: SQLServerの検索結果を正しく出したい
□投稿者/ mo (7回)-(2014/08/05(Tue) 09:44:46)
返信が遅くなってすみません。

■No72899 (PANG2 さん) に返信
>>「stP &= CR(0).ToString()」と「stP &= System.Environment.NewLine」の二か所を削除する事で欲しい動きになりました。
> 
> テキストボックスに % を入力すると、どうなりますか?
> 期待している動きですか?
> 

%を入れると、ラベルに「日産トヨタ三菱」と表示されるようになりました。

http://jeanne.wankuma.com/tips/vb.net/string/indexof.html

このサイトを参考に、textboxに%を入れたらエラーメッセージが表示と再度入力し直す様にアクティブを設定して、担当者の検索をしないコードを作成しましたが上手くいきません。
コード自体に問題があるかと思い、%以外の文字を設定すると正常に動きますが、%を指定する際に特殊なコードが必要になるのでしょうか?


 Private Sub TextBox1_Validating(sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating

 Dim A As Integer = TextBox1.Text.IndexOf("%"c)

        If A > -1 Then
            MessageBox.Show("%のみの検索は出来ません。担当者コードを入力して下さい。","エラー")
            TextBox1.SelectAll()
            Exit Sub
        End If

以下、ここから先は担当者の検索コードになっています。

■No72900 (Hongliang さん) に返信
>>このコードを応用する事で、IDとパスワードが必要なログインコードなどを作る事は可能でしょうか?
> どこにログインするのか、どんなログイン情報が必要なのか、どういう手段でログインするのか、利用許諾等で認められた行為なのか、そういうのをすっ飛ばして可能かどうか論じることは不可能です。

自分がプログラム初心者なので、色々おかしい所もあると思いますが

@SQLServer2008に「利用者コード」というテーブルを作り、利用者IDとパスワードという項目を作成。(下に仮のデータを作りました)
利用者ID パスワード
0001 AAA1
0002 BBB2

AVBでログイン画面を作成し、テキストボックス二個(TeA,TeBとNameを変更),ボタンを一個配置して
TeAに利用者ID、TeBにパスワードを入力しIDとパスワードが一致した場合にのみmenuというフォームを表示させ、一か所でも情報が間違った際にはエラーメッセージを表示させる

というイメージなんですが、論じる事は可能ですか?

引用返信 編集キー/
■72974 / inTopicNo.7)  Re[5]: SQLServerの検索結果を正しく出したい
□投稿者/ キム (14回)-(2014/08/06(Wed) 16:43:53)
No72964 (mo さん) に返信

横槍失礼します。

SQL文を作るのに文字列連結を使っているようですが、これは危険なので避けたほうがよいです。
テキストボックスに悪意を持った入力を行うと、不正にデータを入手したり削除したり出来てしまう可能性があります。
また、ログイン画面に応用すると、パスワード無しで簡単にログインすることも出来てしまいます。
悪意が無くても、誤入力や SQLでは特別な意味を持つ文字を知らずに入力してしまう場合もあり、思わぬ結果を招くことになります。
SQLインジェクションで検索すれば、具体例が沢山出てきます。

ユーザーが入力したパラメーターは、文字列連結ではなく、静的プレースホルダーによってバインドした方がよいです。
.NETであれば、System.Data.SqlClient.SqlParameter を使えばよいです。
SqlCommand.Prepare の例なども理解に役立つと思います。
引用返信 編集キー/
■73028 / inTopicNo.8)  Re[6]: SQLServerの検索結果を正しく出したい
□投稿者/ mo (8回)-(2014/08/12(Tue) 10:58:29)
No72974 (キム さん) に返信
> ■No72964 (mo さん) に返信
> 
> 横槍失礼します。
> 
> SQL文を作るのに文字列連結を使っているようですが、これは危険なので避けたほうがよいです。
> テキストボックスに悪意を持った入力を行うと、不正にデータを入手したり削除したり出来てしまう可能性があります。
> また、ログイン画面に応用すると、パスワード無しで簡単にログインすることも出来てしまいます。
> 悪意が無くても、誤入力や SQLでは特別な意味を持つ文字を知らずに入力してしまう場合もあり、思わぬ結果を招くことになります。
> SQLインジェクションで検索すれば、具体例が沢山出てきます。
> 
> ユーザーが入力したパラメーターは、文字列連結ではなく、静的プレースホルダーによってバインドした方がよいです。
> .NETであれば、System.Data.SqlClient.SqlParameter を使えばよいです。
> SqlCommand.Prepare の例なども理解に役立つと思います。

返信が遅くなってすみません。

http://www.websec-room.com/2013/03/03/365

こちらのサイトに記載していたログインコードを開発環境に合わせる様にコードを変更することで、%を入力しても担当者名を全て表示されないように出来ました。
ログインは本当に必要なのか考えてから作成しようと思っています。

キムさん、PANG2さん、Hongliangさん、ご協力有難うございます。

以下が修正したコードです。

Private Sub TextBox1_Validating(sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating

        If TextBox1.Text.Length = 0 Then
            Label1.Text = ""
            Exit Sub
        End If

        Dim count As Integer = 0

        Dim connectionString As String = "Data Source=PC名;Initial Catalog=テーブル;Integrated Security=True"
        Dim con As SqlConnection = New SqlConnection(connectionString)
        Dim sql As String = "SELECT COUNT(*) AS CNT FROM 担当者一覧 WHERE 担当者コード = @code"
        Dim code As String = Me.TextBox1.Text
        Dim command As SqlCommand = New SqlCommand(sql, con)

        Dim pcode As SqlParameter = New SqlParameter("@code", code)
        command.Parameters.Add(pcode)

        con.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()

        If reader.HasRows Then
            While reader.Read()
                count = CType(reader("CNT"), Integer)
            End While
        End If

        reader.Close()
        con.Close()

        If count = 1 Then
            Try
                Using con2 As New SqlConnection
                    con2.ConnectionString = "Data Source=PC名;Initial Catalog=テーブル名;Integrated Security=True"

                    con2.Open()

                    Dim HC As System.Data.SqlClient.SqlCommand = con2.CreateCommand()
                    HC.CommandText = "SELECT * FROM 担当者一覧 WHERE (担当者コード LIKE '" & TextBox1.Text & "')"
                    Dim CR As System.Data.SqlClient.SqlDataReader = HC.ExecuteReader()

                    HC.Dispose()

                    Dim stP As String = String.Empty
                    While (CR.Read())
                        stP &= CR("担当者名").ToString()
                    End While

                    CR.Close()

                    Label1.Text = stP

                End Using
            Catch ex As Exception

            End Try
        Else
            MessageBox.Show("該当する得意先がありません。再度入力して下さい。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
            TextBox1.Select()
            TextBox1.SelectAll()
        End If
End Sub

解決済み
引用返信 編集キー/
■73031 / inTopicNo.9)  Re[7]: SQLServerの検索結果を正しく出したい
□投稿者/ PANG2 (40回)-(2014/08/12(Tue) 12:15:15)
> 以下が修正したコードです。

無駄な処理が多すぎますね。

> SQLserverの担当者一覧の中身
> 担当者コード 担当者名
> 1000 日産
> 2000 トヨタ
> 3000 三菱
>

担当者コードが一意であることが保障されているとします。(違いますか?)

SELECT 担当者名 FROM 担当者一覧 WHERE 担当者コード = @code

を実行すると、コードが一致すれば単一の担当者名を返します。一致しなければ空を返します。

完全一致で検索しているので、複数個返すことはありえません。
(LIKE だとワイルドカード検索が出来るので複数行返す可能性あり)

結果が単一であることが保障されている場合は、SqlCommand.ExecuteScalar を使うのが最適です。
引用返信 編集キー/
■73039 / inTopicNo.10)  Re[8]: SQLServerの検索結果を正しく出したい
□投稿者/ mo (9回)-(2014/08/13(Wed) 10:28:40)
No73031 (PANG2 さん) に返信
>>以下が修正したコードです。
> 
> 無駄な処理が多すぎますね。
> 
>>SQLserverの担当者一覧の中身
>>担当者コード 担当者名
>>1000 日産
>>2000 トヨタ
>>3000 三菱
>>
> 
> 担当者コードが一意であることが保障されているとします。(違いますか?)
> 
> SELECT 担当者名 FROM 担当者一覧 WHERE 担当者コード = @code
> 
> を実行すると、コードが一致すれば単一の担当者名を返します。一致しなければ空を返します。
> 
> 完全一致で検索しているので、複数個返すことはありえません。
> (LIKE だとワイルドカード検索が出来るので複数行返す可能性あり)
> 
> 結果が単一であることが保障されている場合は、SqlCommand.ExecuteScalar を使うのが最適です。

PANG2さん、修正のヒントを有難うございます。
ヒントのお陰で、無駄な箇所を削る事が出来ました。
確認ですが担当者コードが一意であるというのは、担当者コードのかぶりは一切無いという事でしょうか?
下のコードはかぶりが一切無い前提で動いています。


 If TextBox1.Text.Length = 0 Then
            Label1.Text = ""
            Exit Sub
        End If

        Dim count As String = ""
        Dim connectionString As String = "Data Source=PC名;Initial Catalog=テーブル名;Integrated Security=True"
        Dim con As SqlConnection = New SqlConnection(connectionString)
        Dim sql As String = "SELECT 担当者名 AS CNT FROM 担当者一覧 WHERE 担当者コード = @code"
        Dim code As String = Me.TextBox14.Text
        Dim command As SqlCommand = New SqlCommand(sql, con)

        Dim pcode As SqlParameter = New SqlParameter("@code", code)
        command.Parameters.Add(pcode)

        con.Open()

        Dim reader As SqlDataReader = command.ExecuteReader()

        If reader.HasRows Then
            While reader.Read()
                count = CType(reader("CNT"), String)
            End While
        End If

        reader.Close()
        con.Close()

        If count = "" Then
            MessageBox.Show("該当する担当者がありません。再度入力して下さい。", "担当者エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
            TextBox1.Select()
            TextBox1.SelectAll()
        Else
            Label1.Text = count
            TextBox2.Select()
        End If


解決済み
引用返信 編集キー/
■73052 / inTopicNo.11)  Re[9]: SQLServerの検索結果を正しく出したい
□投稿者/ まさや (3回)-(2014/08/13(Wed) 23:58:22)
「データベース処理を行うとき」は、Usingステートメントは必須です。
もしくはTry Catch Finally。
使用しない人は、コードを書くのやめたほうがいいです。

担当者コードがユニークかどうかは、SQLServerのテーブル定義を見ればわかります。
デザインを開いて鍵のマークがそこだけに付いてたら問題なし。

connectionString は、App.configから取得するようにしときなよ。

カラ文字比較はString.IsNullOrEmptyを使用してね。

変数名のcountとか、SQLのリネームに使用しているCNTはとてもわかりづらいです。
TANTOUとかtantoでいいじゃん。車はダイハツになっちゃうけどね。

No73039 (mo さん) に返信
> ■No73031 (PANG2 さん) に返信
> >>以下が修正したコードです。
>>
>>無駄な処理が多すぎますね。
>>
> >>SQLserverの担当者一覧の中身
> >>担当者コード 担当者名
> >>1000 日産
> >>2000 トヨタ
> >>3000 三菱
> >>
>>
>>担当者コードが一意であることが保障されているとします。(違いますか?)
>>
>>SELECT 担当者名 FROM 担当者一覧 WHERE 担当者コード = @code
>>
>>を実行すると、コードが一致すれば単一の担当者名を返します。一致しなければ空を返します。
>>
>>完全一致で検索しているので、複数個返すことはありえません。
>>(LIKE だとワイルドカード検索が出来るので複数行返す可能性あり)
>>
>>結果が単一であることが保障されている場合は、SqlCommand.ExecuteScalar を使うのが最適です。
>
> PANG2さん、修正のヒントを有難うございます。
> ヒントのお陰で、無駄な箇所を削る事が出来ました。
> 確認ですが担当者コードが一意であるというのは、担当者コードのかぶりは一切無いという事でしょうか?
> 下のコードはかぶりが一切無い前提で動いています。
>
>
> If TextBox1.Text.Length = 0 Then
> Label1.Text = ""
> Exit Sub
> End If
>
> Dim count As String = ""
> Dim connectionString As String = "Data Source=PC名;Initial Catalog=テーブル名;Integrated Security=True"
> Dim con As SqlConnection = New SqlConnection(connectionString)
> Dim sql As String = "SELECT 担当者名 AS CNT FROM 担当者一覧 WHERE 担当者コード = @code"
> Dim code As String = Me.TextBox14.Text
> Dim command As SqlCommand = New SqlCommand(sql, con)
>
> Dim pcode As SqlParameter = New SqlParameter("@code", code)
> command.Parameters.Add(pcode)
>
> con.Open()
>
> Dim reader As SqlDataReader = command.ExecuteReader()
>
> If reader.HasRows Then
> While reader.Read()
> count = CType(reader("CNT"), String)
> End While
> End If
>
> reader.Close()
> con.Close()
>
> If count = "" Then
> MessageBox.Show("該当する担当者がありません。再度入力して下さい。", "担当者エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
> TextBox1.Select()
> TextBox1.SelectAll()
> Else
> Label1.Text = count
> TextBox2.Select()
> End If
>
>
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -