2016-12-12 2 views
0

Ich versuche, ein altes visuelles Basisprogramm, das Legacy-Datenbanktabellen verwendet, in eine modernere und robustere Implementierung zu konvertieren. Es verwendet eine Menge von Varchars, wenn es Floats hätte verwenden sollen, um ein konkretes Beispiel zu geben, es macht den Code sehr schwer zu lesen, da viele Konvertierungen von Float zu String und Reverse benötigt werden, was ich in der neuen Anwendung vermeiden möchte)Aktualisierbare Ansicht gibt Laufzeitfehler in Visual Basic

Um Abwärtskompatibilität zu erhalten, erstelle ich aktualisierbare Ansichten auf meinen neuen Tabellen, so dass die alte Anwendung in vb noch funktionieren kann oder zumindest das ist die Absicht.

Ich habe eine Ansicht wie folgt:

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 

und dann habe ich anstelle des Einsatzes erstellt und statt Update auf dieser Ansicht löst es aktualisierbar und manuell diese Trigger getestet, um zu bestätigen, dass sie in Ordnung sind, und sie arbeiten.

Wenn ich jedoch als letzter Test versuche, das VB6-Programm auszuführen, kann es keine Inserts mehr machen, noch bevor ich den Insert tatsächlich gemacht habe. Der Code nicht in VB sich in der OLE-Material:

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

Die Abfrage hinter dem rsSelectedArtikel ist eine einfache select * from Orders_Catalogen_artikels, die den Namen der Ansicht ist, die ich oben zeigte.

¨Der Laufzeitfehler, den ich bekomme, ist -2147217887 (8004e21), der normalerweise eine falsche Typverwendung oder etwas ähnliches identifizieren würde. Aber der Aantal wird korrekt als ein nvarchar (5) identifiziert, wenn ich die Spalten der Ansicht nachschaue.

Gibt es eine Lösung oder einen Workaround für diese Art von Problem?

Ich könnte natürlich weiterhin die alte Tabellendefinition verwenden Strings für Längen und Breiten und dergleichen, und erstellen Sie eine aktualisierbare Ansicht für die neue Anwendung, aber das scheint für mich das Gegenteil der richtige zu tun.

Oder ich modifiziere die VB-Anwendung leicht, ich habe die Quellen und modifiziere zuerst das Datenmodell, um Floats für Breiten, Höhen und Längen zu verwenden, aber ich bevorzuge, es unberührt zu lassen.

Ich hätte gehofft, dass aktualisierbare Ansichten die Antwort für diese Art von Problem waren.

UPDATE 1: Hinzufügen von Update-Trigger und Insert-Trigger

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' ist der gefürchtete' DB_E_ERRORSOCCURRED', was bedeutet "etwas ist schief gelaufen, finde es selbst heraus". Das Aktualisieren einer Ansicht mit einem 'INSTEAD OF'-Trigger unter Verwendung des Standorts eines serverseitigen dynamischen Cursors * ist * möglich (ich habe es in T-SQL versucht), und das sollte * sein, was ADO verwendet.Um sicher zu gehen, versuchen Sie, die Anweisung mit SQL Profiler zu verfolgen, um zu sehen, was sie wirklich macht. Fügen Sie "Fehler" -Ereignisse für maximale Hilfsbereitschaft ein. Wenn Ihr Re-Cord-Set clientseitig oder getrennt ist, wird das Problem wahrscheinlich sein, dass ADO "weiß", dass Sie berechnete Spalten nicht aktualisieren können, aber das Basisszenario sollte möglich sein. –

+0

Ich werde morgen einen Blick auf Ihren Vorschlag werfen, aber ich denke, das Problem ist Client-Seite. Ich erwarte einen Hin- und Rückweg zum Server nicht als einen Punkt, an dem die Aufgabe stattfindet. Sehr hilfreicher Kommentar danke. –

+0

Wenn das Problem Computerspalten sind, besteht eine mögliche, aber möglicherweise sehr ressourcenintensive Problemumgehung darin, sie in ein neues Recordset zu kopieren, bei dem die Spalten nicht auf "computed" gesetzt sind. ADO wird also Updates erlauben - so lange sie es schaffen Bei SQL Server sollte der Trigger den Rest übernehmen. An diesem Punkt sind Sie jedoch daran gewöhnt, Code zu modifizieren (selbst wenn es nur das Recordset umschließt), und es lohnt sich, darüber nachzudenken, ob die Dinge sowieso nicht neu geschrieben werden sollten. (Ich habe auch keine Ahnung, ob das tatsächlich funktioniert. Vor ein paar Jahren musste ich mit ADO arbeiten. :-)) –

Antwort

0

An "aktualisierbar" Ansicht ist eine falsche Bezeichnung. Die Ansicht speichert nichts. Die Alias-Spalten geben ein geändertes Aussehen der Daten in der Tabelle zurück.

In Ihrem Beispiel haben Sie zwei mögliche Codepfade für einen einzelnen Wert (null oder nicht null). Sie versuchen, Code zurück in einen der Codepfade zu senden, um einen Basiswert zu erhalten. Wenn Sie zum Beispiel '' den Pfad hinunter geschickt haben, wie würde SQL wissen, ob das ein Literal sein soll '' oder ein Nullwert, der ersetzt wurde.

Aus diesem Grund können Sie keine Spalten mit einem Ausdruck aktualisieren. Der Ausdruck ist in der Ansicht effektiv schreibgeschützt.

+0

Ich erklärte, ich benutze statt Trigger, um eine Ansicht aktualisierbar zu machen. Diese Trigger behandeln dasselbe, aber umgekehrt wie die Ansicht. –

+0

Nur damit mir klar ist, du verwendest einen statt Trigger auf die Ansicht. Wenn eine Anweisung versucht, die Ansicht zu aktualisieren, übernimmt der Trigger stattdessen eine Aktualisierungsanweisung und führt sie aus. –

+0

Wenn meine obige Aussage richtig ist, können Sie die Definition Ihres Triggers posten? –