3

特定の解決策を求めるのは嫌いなので、間違った方法でアプローチしている場合に備えて、質問の背景を次に示します。背景をスキップして質問に直接進みたい場合は、太字の行までスキップしてください。SQL データベースからのデータが事前入力される PDF フォームを作成しています。これを行うには、データをデータベースから XFDF ファイルにエクスポートする必要があります。これにより、空白の PDF フォームと簡単にマージして値を入力できます。

XFDF ファイルの形式は次のとおりです。

<fields>
    <field name="FirstName">
        <value>John</value>
    </field>
    <field name="LastName">
        <value>Smith</value>
    </field>
</fields>

ここで、"FirstName" と "LastName" は PDF フォームのフィールド名に対応し、"John" と "Smith" はフォームに入力するデータベースからの対応する値です。

したがって、私の目標は、XFDF ファイルを作成し、PDF のフィールドの名前をテーブルの列の名前に対応させることです。私の現在のアプローチは、SELECT FOR XML EXPLICIT ステートメントを使用することです。これを使用するには、最初にデータを選択して、for xml の明示的なステートメントで必要な「ユニバーサル テーブル」形式にする必要があります。これにより、元のデータ テーブルの列ごとに個別の行が作成されます。各フィールドを手動で調べて、列ごとに個別の select ステートメントを記述できます。たとえば、FirstName 列部分は次のようになります。

SELECT  2               AS Tag,
        1               AS Parent,
        null            AS [fields!1],
        FirstName       AS [fields!2!name],
        D.FirstName     AS [value!3!]
From    Data AS D

(select for XML ステートメントの正確な構文であるかどうかはわかりませんが、そのようなものである必要があります)

元のテーブルの各列に対してそのような select ステートメントを実行した場合 (さらに、ルート レベルの "fields" 要素に対して 1 つを追加し、それらを結合すると、SELECT FOR XML EXPLICIT ステートメントを実行するために必要なテーブルが作成されます。

ただし、このフォームには大量のフィールドがあり (政府機関! ええ!)、これをプログラムで行う何らかの方法を希望します。

背景を説明したので、ここに私の実際の質問があります。背景を読んで私のアプローチがおかしいと思われる場合は、お知らせください。

次のような行を含むテーブルを取得する方法が必要です。

+----------+----------+-----+
| | ファーストネーム | 姓 | その他 |
+----------+----------+-----+
| | ジョン | スミス | 123 |
+----------+----------+-----+

それから次のような新しいテーブルを作成します。

+----------+-------+
| | フィールド名 | 値 |
+----------+-------+
| | ファーストネーム | ジョン |
| | 姓 | スミス |
| | その他 | 123 |
+----------+-------+

これが有効であれば、次のようにします。

SELECT  2               AS Tag,
        1               AS Parent,
        null            AS [fields!1],
        C.column_name       AS [fields!2!name],
        D.{C.column_name}       AS [value!3!]
From        Data AS D, information_schema.columns AS C 
WHERE   C.table_name = 'Data'   

明らかにそれは不可能であり、選択されている列を変数にすることはできません。私はこの質問 ( SQL サーバー 2008 の Select ステートメントで変数列名を使用する) を見て、一番上の答えは有望かもしれませんが、「しかし、それはすべてかなり恐ろしい、私見です」で終わります。その道に着手する前に、「かなり恐ろしい」ものではない解決策を検討したいと思います. 助言がありますか?

4

3 に答える 3

1

MS SQL 2008で使用できるUNPIVOT問題は、すべての列で同じデータ型と照合を使用するか、以下の例のように変換を行う必要があることです。結果はあなたが望むものとまったく同じになるはずです

SELECT seq,ts
FROM 
    (select 

  convert(nvarchar(200),FirstName) COLLATE Latin1_General_CI_AS  as FirstName,
  convert(nvarchar(200),LastName) COLLATE Latin1_General_CI_AS  as LastName,
  convert(nvarchar(200),Etc) COLLATE Latin1_General_CI_AS  as Etc,

    from youPersonTable P 
       where  id = 1
) p
UNPIVOT
    (ts FOR Seq IN 
        (FirstName,LastName,Etc)
) AS unpvt
于 2013-02-01T17:41:06.797 に答える
0

別のオプションは、2 つのテーブルと一時テーブルを使用することです。

tblEmployee
tblXTABEmployee --This table basically swaps the rows for columns.
tmpXTABEmployee

次のコマンドを使用して、tblEmployee のすべての列名を取得できます。

EXEC sp_help tblEmployee

次に、カーソルを使用して tblXTABEmployee を設定できます。詳細が必要な場合はお気軽にお問い合わせください。

更新: sp_help を使用してすべての列名を選択する tmpXTABEmployee を作成し、次のようなカーソルを使用する必要があります (これはテストしていないことに注意してください)。

declare @ColumnName nvarchar(255)
declare @SQLString nvarchar(4000)
declare columnNameCursor cursor for

SELECT     ColumnName
FROM       tmpXTABEmployee
GROUP BY ColumnName
ORDER BY ColumnName

OPEN columnNameCursor

FETCH NEXT FROM columnNameCursor INTO @ColumnName

BEGIN TRY
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @SQLString = 'INSERT INTO dbo.tblXTABEmployee (FieldName, DataValue) VALUES (' + @ColumnName + ', ' + dbo.tmpXTABEmployee.DataValue + ')'
    EXEC (@SQLString)
    FETCH NEXT FROM columnNameCursor INTO @ColumnName
END
END TRY 
BEGIN CATCH
DECLARE @msg VARCHAR(4096)
SET @msg = 'Failure occurred attempting to insert into tblXTABEmployee.';
RAISERROR(@msg, 0, 1);
END CATCH

CLOSE columnNameCursor
DEALLOCATE columnNameCursor
GO
于 2013-02-01T18:12:33.650 に答える
0

を使用してテーブルをクエリしfor xml、結果を XML 変数に格納します。local-name(.)次に、XML 変数を照会して、XML 変数から列/ノード名を取得するために使用する必要がある XML の形状を作成します。

SQL フィドル

MS SQL Server 2008 スキーマのセットアップ:

create table YourTable
(
  FirstName varchar(25),
  LastName varchar(25),
  Etc int
)

insert into YourTable values ('John', 'Smith', 123)

クエリ 1 :

declare @XML xml

set @XML = (
           select *
           from YourTable
           for xml path('row'), type
           )

select T.N.value('local-name(.)', 'sysname') as "@name",
       T.N.value('text()[1]', 'varchar(max)') as "value"
from @XML.nodes('/row/*') as T(N)
for xml path('field'), root('fields')

結果

<fields>
  <field name="FirstName">
    <value>John</value>
  </field>
  <field name="LastName">
    <value>Smith</value>
  </field>
  <field name="Etc">
    <value>123</value>
  </field>
</fields>
于 2013-02-01T22:30:08.600 に答える