sql >> データベース >  >> RDS >> Sqlserver

Linuxでpyodbcを使用して、nvarcharmssqlフィールドにunicodeまたはutf-8文字を挿入します

    当時はjavaとoracleの組み合わせであったとしても、odbcドライバーを使用してこの種の愚かな問題が発生したことを覚えています。

    重要なのは、odbcドライバーがクエリ文字列をDBに送信するときに明らかにエンコードすることです。フィールドがUnicodeであり、Unicodeを提供している場合でも、問題にならない場合があります。

    ドライバによって送信されるものがデータベース(サーバーだけでなくデータベースも)と同じエンコーディングであることを確認する必要があります。そうしないと、もちろん、クライアントまたはサーバーのいずれかがエンコード/デコード時に物事を混同しているため、ファンキーな文字が表示されます。サーバーがデータをデコードするためのデフォルトとして使用している文字セット(MSが言うようにコードポイント)について何か考えがありますか?

    照合はこの問題とは何の関係もありません:)

    そのMSページ を参照してください。 例えば。 Unicodeフィールドの場合、照合は列の並べ替え順序を定義するためにのみ使用され、ではありません データの保存方法を指定します。

    データをUnicodeとして保存する場合、それを表す独自の方法があります。それがUnicodeの目的です。使用するすべての言語と互換性のある文字セットを定義する必要はありません:)

    ここでの質問は、「サーバーにではないデータを提供するとどうなるか」です。 Unicode?」。例:

    • UTF-8文字列をサーバーに送信すると、どのように理解されますか?
    • UTF-16文字列をサーバーに送信すると、どのように理解されますか?
    • Latin1文字列をサーバーに送信すると、どのように理解されますか?

    サーバーの観点からは、これら3つの文字列はすべてバイトのストリームにすぎません。サーバーは、それらをエンコードしたエンコードを推測できません。つまり、 odbcクライアントがbytestringsを送信してしまうと、問題が発生します (エンコードされた文字列) unicode を送信する代わりに、サーバーに送信します データ:そうする場合、サーバーは事前定義されたエンコーディングを使用します(これは私の質問です:サーバーが使用するエンコーディングは何ですか?推測ではないため、パラメータ値である必要があります)。別のエンコーディング、 dzing 、データが破損します。

    Pythonで行うのとまったく同じです:

    uni = u'Hey my name is André'
    in_utf8 = uni.encode('utf-8')
    # send the utf-8 data to server
    # send(in_utf8)
    
    # on server side
    # server receives it. But server is Japanese.
    # So the server treats the data with the National charset, shift-jis:
    some_string = in_utf8 # some_string = receive()    
    decoded = some_string.decode('sjis')
    

    やってみなよ。楽しいです。デコードされた文字列は「HeymynameisAndré」であるはずですが、「Hey my name isAndr テゥ」です。 éは日本語に置き換えられますテゥ

    したがって、私の提案:pyodbcがデータをUnicodeとして直接送信できることを確認する必要があります。 pyodbcがこれを実行できない場合、予期しない結果が発生します。

    そして、私はクライアントからサーバーへの方法で問題を説明しました。ただし、サーバーからクライアントに通信する場合にも、同じ種類の問題が発生する可能性があります。クライアントがUnicodeデータを理解できない場合、問題が発生する可能性があります。

    FreeTDSはUnicodeを処理します。

    実際、FreeTDSが自動的に処理を行い、すべてのデータをUCS2ユニコードに変換します。 (出典

    • サーバー<->FreeTDS:UCS2データ
    • FreeTDS <-> pyodbc:エンコードされた文字列。UTF-8でエンコードされています(/etc/freetds/freetds.confから) )

    したがって、UTF-8データをpyodbcに渡すと、アプリケーションが正しく機能することが期待されます。実際、このdjango-pyodbcチケット 状態、django-pyodbcはUTF-8でpyodbcと通信するので、問題ないはずです。

    FreeTDS 0.82

    ただし、 cramm0 FreeTDS 0.82は完全にバグがないわけではなく、0.82とパッチが適用された公式の0.82バージョンとの間には大きな違いがあります。ここ 。パッチを適用したFreeTDSを使用してみてください

    編集済み古いデータを削除しました。これはFreeTDSとは関係ありませんが、Easysoftの商用odbcドライバーにのみ関連していました。申し訳ありません。



    1. PHPMySQLDBからの結果の順序を逆にします

    2. SQL QUERY 1つの行を複数検索して、同じテーブルの別の行のデータを検索します

    3. PostgreSQL 13:制限…タイ付き

    4. 生成されたSQLを変数から実行するにはどうすればよいですか?