2016-12-12 8 views
0

レガシーデータベーステーブルを使用している古いビジュアル基本プログラムをより現代的で堅牢な実装に変換しようとしています。具体的な例を示すために浮動小数点数を使用する必要があるときは、多くのvarcharsを使用する必要があります。浮動小数点数から文字列への変換回数が多いため、コードを読みにくくなります。新しいアプリケーションでは避けたいです)更新可能なビューはビジュアルベーシックでランタイムエラーを表示します

下位互換性を維持するために、新しいテーブルで更新可能なビューを作成して、vbの古いアプリケーションが引き続き動作するようにするか、少なくともそれが意図です。 、

SELECT   
ArtikelNummer, 
CataloogID, 
Artikel, 
isnull(CONVERT(nvarchar(5), breedte),'') Breedte, 
isnull(CONVERT(nvarchar(5), Hoogte),'') Hoogte, 
isnull(CONVERT(nvarchar(5), Diepte),'') Diepte, 
isnull(CONVERT(nvarchar(5), Aantal),'') Aantal, 
FROM    
Master.Orders_Catalogen_Artikels 

をして、私の代わりに、インサートの作成し、更新が、このビューでトリガーの代わりに、それは更新可能にし、手動で、彼らがOKであることを検証するためにこれらのトリガーをテストするために以下のような

は、私は、ビューを持っています彼らは働く。

しかし、最終テストでVB6プログラムを実行しようとすると、実際に挿入を実行する前に挿入を実行できません。コードは、OLEのものでVB自体に失敗:

With MyDE.rsSelectedArtikel 
.Fields("CataloogID").Value = Orders.cCataloogID 
.Fields("Artikel").Value = Orders.cbArtikel 
.Fields("Aantal").Value = Orders.cAantal ---> fails here 

rsSelectedArtikelの背後にあるクエリは、私が上記示したビューの名前ですOrders_Catalogen_artikelsから*簡単な選択です。

私が得るランタイムエラーは、通常、間違ったタイプの使用法などを識別する-2147217887(8004e21)です。しかし、Aantalは、ビューの列を参照するとき、nvarchar(5)として正しく識別されます。

この種の問題の修正または回避策はありますか?

もちろん、長さと幅などの文字列を使用して古いテーブル定義を使用して、新しいアプリケーションのupdatebleビューを作成することもできますが、それは正しいことの逆です。

VBのアプリケーションを少し修正します。ソースがあります。最初に、幅、高さ、長さに浮動小数点数を使用するようにデータモデルを変更しますが、私の好みはそのままです。

私は、更新可能なビューがこの種の問題に対する答えであることを期待していました。

UPDATE 1: "更新可能" ビューが誤った名称である更新トリガーと挿入トリガー

ALTER TRIGGER [dbo].[V_Orders_Catalogen_Artikels_Update] ON [dbo].[Orders_Catalogen_Artikels] 
INSTEAD OF UPDATE 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for trigger here 
UPDATE [Master].[Orders_Catalogen_Artikels] 
SET [CataloogID] = inserted.CataloogID 
    ,[Artikel] = inserted.Artikel 
    ,[Breedte] = iif(inserted.Breedte = '',null,inserted.Breedte) 
    ,[Hoogte] = iif(inserted.Hoogte = '',null,inserted.Hoogte) 
    ,[Diepte] = iif(inserted.Diepte = '',null,inserted.Diepte) 
    ,[Aantal] = iif(inserted.Aantal = '',null,inserted.Aantal) 
    ,[OmschrijvingNL] = inserted.OmschrijvingNL 
    ,[Positie] = inserted.Positie 
    ,[EenheidsPrijs] = inserted.EenheidsPrijs 
    ,[Opmerking] = inserted.Opmerking 
    ,[PosNr] = inserted.PosNr 
    ,[Binnenkleur] = inserted.Binnenkleur 
    ,[BKleurFront] = inserted.BKleurFront 
    ,[Frontkantdikte] = inserted.Frontkantdikte 
    ,[Poothoogte] = inserted.Poothoogte 
    ,[BTWcode] = inserted.BTWcode 
    ,[Korpuskantdikte] = inserted.Korpuskantdikte 
    ,[ManuelePrijs] = inserted.ManuelePrijs 
    ,[OpmerkingFr] = inserted.OpmerkingFr 
    ,[OmschrijvingFr] = inserted.OmschrijvingFr 
    ,[ArtikelGroepID] = inserted.ArtikelGroepID 
    ,[ArtikelID] = inserted.ArtikelID 
    ,[VolgNr] = inserted.VolgNr 
    ,[Klaar] = inserted.Klaar 
    ,[ScanDatum] = inserted.ScanDatum 
    ,[ScanOpm] = inserted.ScanDatum 
    ,[OpZaaglijst] = inserted.OpZaaglijst 
FROM inserted 
WHERE [Master].[Orders_Catalogen_Artikels].ArtikelNummer = inserted.ArtikelNummer 

END 

ALTER TRIGGER [dbo].[V_Orders_Catalogen_Artikels_Insert] ON [dbo].[Orders_Catalogen_Artikels] 
INSTEAD OF INSERT 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for trigger here 
INSERT INTO [Master].[Orders_Catalogen_Artikels] 
     ([CataloogID] 
     ,[Artikel] 
     ,[Breedte] 
     ,[Hoogte] 
     ,[Diepte] 
     ,[Aantal] 
     ,[OmschrijvingNL] 
     ,[Positie] 
     ,[EenheidsPrijs] 
     ,[Opmerking] 
     ,[PosNr] 
     ,[Binnenkleur] 
     ,[BKleurFront] 
     ,[Frontkantdikte] 
     ,[Poothoogte] 
     ,[BTWcode] 
     ,[Korpuskantdikte] 
     ,[ManuelePrijs] 
     ,[OpmerkingFr] 
     ,[OmschrijvingFr] 
     ,[ArtikelGroepID] 
     ,[ArtikelID] 
     ,[VolgNr] 
     ,[Klaar] 
     ,[ScanDatum] 
     ,[ScanOpm] 
     ,[OpZaaglijst]) 
     SELECT 
    [CataloogID] 
    ,[Artikel] 
    ,iif(ISNUMERIC(breedte+'e0')=1,convert(float,[Breedte]),null) as newbreedte 
    ,iif(ISNUMERIC([Hoogte]+'e0')=1,convert(float,[Hoogte]),null) as newhoogte 
    ,iif(ISNUMERIC([Diepte]+'e0')=1,convert(float,[Diepte]),null) as newdiepte 
    ,iif(ISNUMERIC([Aantal]+'e0')=1,convert(float,[Aantal]),null) as newaantal 
    ,[OmschrijvingNL] 
    ,[Positie] 
    ,[EenheidsPrijs] 
    ,[Opmerking] 
    ,[PosNr] 
    ,[Binnenkleur] 
    ,[BKleurFront] 
    ,[Frontkantdikte] 
    ,[Poothoogte] 
    ,[BTWcode] 
    ,[Korpuskantdikte] 
    ,[ManuelePrijs] 
    ,[OpmerkingFr] 
    ,[OmschrijvingFr] 
    ,[ArtikelGroepID] 
    ,[ArtikelID] 
    ,[VolgNr] 
    ,[Klaar] 
    ,[ScanDatum] 
    ,[ScanOpm] 
    ,[OpZaaglijst] 
FROM inserted 

END 
+1

「80040e21」は恐ろしい 'DB_E_ERRORSOCCURRED'です。これは「何かが間違っていて、あなた自身でそれを理解してください」という意味です。サーバー側の動的カーソル*の位置を使って 'INSTEAD OF'トリガーでビューを更新することは可能です(T-SQLで試しました)。* ADOが使用するものでなければなりません。確かに知るには、SQL Profilerでそのステートメントをトレースして、実際に何が行われているかを確認してください。最大限の有用性のために「エラー」イベントを含める。レコードセットがクライアント側または切断されている場合、ADOは計算列を更新できないことを「認識」している可能性がありますが、基本的なシナリオは可能である必要があります。 –

+0

私はあなたの提案を見るためにtommorrow見ているが、私は問題がクライアント側だと思う。私はサーバーへの往復が、割り当てが行われている時点ではないと考えています。非常に役に立つコメントをありがとうございます。 –

+0

問題がコンピュータの列である場合、潜在的だが恐らく非常にリソースがかかる可能性のある回避策は、計算されるように設定された列を持たない新しいレコードセットにコピーすることです。 SQL Serverに、トリガは残りの部分を処理する必要があります。しかし、その時点では、(レコードセットをラップするだけであっても)コードを変更することになります。とにかく書き直してはならないと考える価値があります。 (私もADOで作業しなければならなかったので、数年経ちました:-)) –

答えて

0

を加えます。ビューには何も保存されません。エイリアス化された列は、表内のデータを変更した外観を返します。

この例では、1つの値(nullまたはnullではない)に対して2つのコードパスがあります。コードパスの1つを元に戻って基本値に到達しようとしています。例えば、あなたがパスを送ったとしたら、それがリテラルでなければならないかどうか、あるいは置き換えられたヌル値をSQLがどのように知っていますか?

このため、式を含む列は更新できません。この式は、ビューで効果的に読み取り専用になります。

+0

私は私がトリガーの代わりにビューを更新可能にするために使用すると説明しました。これらのトリガーは同じことを処理しますが、ビューの処理とは逆です。 –

+0

ちょうど私ははっきりしている、あなたはビューのトリガーの代わりに使用しています。ステートメントがビューを更新しようとすると、代わりに更新ステートメントが引き継がれ、トリガーが実行されます。 –

+0

上記の私の記述が正しい場合は、あなたのトリガーの定義を投稿できますか? –

関連する問題