XMLでフォームのレイアウトを定義するテーブルがあります。その<Control ...>
中には、Id(GUID)やDataType(char)などの属性を持つノードがあります。
このXMLデータは、実行時にフォームを作成するために使用されます。データが保存されると<Field ...>
、Name(コントロールノードのIDのGUIDと一致)およびData(以前の値を保持する)の属性を持つ呼び出された要素でXMLに書き込まれます。コントロールに入った)。
Dateオブジェクトを.ToStringすると、マシンの日付形式の設定が使用されるという問題があります。したがって、日付は任意の形式で保存できます。常に日付を形式で保存するようにコードを更新しましたYYYY/MM/DD
が、データベース内の既存のデータをに更新する必要がありますYYYY/MM/DD
。日付がどの形式で保存されたかを知る方法がないため、日付がとして保存されたと想定しMM/DD/YYYY
ます。
だから今私の問題はSQLServerでXMLを更新しようとしています。xqueryとCROSSAPPLY.nodes()を使用して、誤ってフォーマットされた日付をすべて見つけるクエリを作成できますが、それらを更新する方法がわかりません。
このSQLスクリプトは、テーブル変数を作成し、それらにいくつかのテストデータを入力し、誤った日付の値を返すクエリを備えています。コメントアウトされている最後の部分は、私がそれらを新しいYYYY/MM/DD
形式に更新しようとした方法ですが、コメントを外すと、機能しないことがわかります。
誰かアイデアはありますか?
PSこれはSQLスクリプトでのみ実行できます。これは、すべてのxmlデータを読み取り、属性を更新してからデータをデータベースに保存する関数を.NETで作成するのが非常に簡単であることを私は知っていますが、この場合、次の理由で不可能です。理由。
DECLARE @Form AS Table
(
FormID INT,
FormDataXML XML
);
DECLARE @ScreenData AS Table
(
ScreenDataID INT,
FormID INT,
ScreenDataXML XML
);
DECLARE @ControlsToUpdate AS TABLE
(
FormID INT,
ControlID char(36),
DataType CHAR(1)
);
INSERT INTO @Form
VALUES (1, '<Form><Control Id="00000000-0000-0000-0000-000000000000" DataType="D" /><Control Id="00000000-0000-0000-0000-000000000001" DataType="N" /></Form>');
INSERT INTO @Form
VALUES (2, '<Form><Control Id="00000000-0000-0000-0000-000000000002" DataType="D" /><Control Id="00000000-0000-0000-0000-000000000003" DataType="D" /></Form>');
INSERT INTO @ScreenData
VALUES (1, 1, '<ScreenData><Field Name="00000000-0000-0000-0000-000000000000" Data="01/31/2012" /><Field Name="00000000-0000-0000-0000-000000000001" Data="1234.56" /></ScreenData>');
INSERT INTO @ScreenData
VALUES (2, 1, '<ScreenData><Field Name="00000000-0000-0000-0000-000000000000" Data="02/28/2013" /><Field Name="00000000-0000-0000-0000-000000000001" Data="0" /></ScreenData>');
INSERT INTO @ScreenData
VALUES (3, 2, '<ScreenData><Field Name="00000000-0000-0000-0000-000000000002" Data="03/31/2013" /><Field Name="00000000-0000-0000-0000-000000000003" Data="04/30/2013" /></ScreenData>');
INSERT INTO @ScreenData
VALUES (4, 2, '<ScreenData><Field Name="00000000-0000-0000-0000-000000000002" Data="2013/05/31" /><Field Name="00000000-0000-0000-0000-000000000003" Data="2013/06/30" /></ScreenData>');
--Data treated as scheduled items
INSERT INTO @ScreenData
VALUES (5, 2, '<ScreenData><Item><Field Name="00000000-0000-0000-0000-000000000002" Data="01/01/2012" /><Field Name="00000000-0000-0000-0000-000000000003" Data="02/02/2012" /></Item><Item><Field Name="00000000-0000-0000-0000-000000000002" Data="03/03/2012" /><Field Name="00000000-0000-0000-0000-000000000003" Data="04/04/2012" /></Item></ScreenData>')
INSERT INTO @ControlsToUpdate
SELECT FormID,
data.control.value('@Id', 'char(36)'),
data.control.value('@DataType', 'char(1)')
FROM @Form
CROSS APPLY FormDataXML.nodes('//Control') data(control)
WHERE data.control.value('@DataType', 'char(1)') = 'D';
--This will display the ScreenDataID, FormID, ControlID, and current Date value for dates that are in the old mm/dd/yyyy format
SELECT d.ScreenDataID, d.FormID, c.ControlID,
data.field.value('@Data', 'char(10)') as Date
FROM @ScreenData d
CROSS APPLY d.ScreenDataXML.nodes('//Field') as data(field)
INNER JOIN @ControlsToUpdate c ON c.ControlID = data.field.value('@Name', 'CHAR(36)')
AND d.FormID = c.FormID
WHERE data.field.value('@Data', 'char(10)')
LIKE '[01][0123456789]/[0123][0123456789]/[12][0123456789][0123456789][0123456789]';
--UPDATE d
--SET data.field.modify('replace value of (/@Data) with "' +
-- SUBSTRING(data.field.value('@Data', 'char(10)'), 7, 4) + '/' +
-- SUBSTRING(data.field.value('@Data', 'char(10)'), 1, 2) + '/' +
-- SUBSTRING(data.field.value('@Data', 'char(10)'), 4, 2) + '"')
--FROM @ScreenData d
--CROSS APPLY d.ScreenDataXML.nodes('//Field') as data(field)
--INNER JOIN @ControlsToUpdate c ON c.Id = data.field.value('@Name', 'CHAR(36)')
-- AND d.FormID = c.FormID
--WHERE data.field.value('@Data', 'varchar(MAX)')
--LIKE '[01][0123456789]/[0123][0123456789]/[12][0123456789][0123456789][0123456789]';
GO
--編集--@ScreenDataのxmlには、<Item>
ノードを含むノードを含めることもできます<Field>
。<Field>
これが発生すると、同じName属性値を持つ複数のノードが作成されます。これは、画面にアイテムのリストビューがある場合で、それぞれが同じコントロールを参照しているが、独自の値を持つ複数のアイテムがあります。ScreenDataID5はこれを示しています。