Я пытаюсь преобразовать старую программу Visual Basic, которая использует устаревшие таблицы базы данных, в более современную и надежную реализацию. Он использует много 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
а затем я создал триггеры вместо вставки и вместо триггеров обновления в этом представлении, чтобы сделать его обновляемым, и вручную протестировал эти триггеры, чтобы убедиться, что они в порядке и работают.
Однако, когда в качестве окончательного теста я пытаюсь запустить программу VB6, она не может выполнить вставку даже до того, как она будет выполнена. Код не работает в самом VB в OLE:
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), когда я просматриваю столбцы представления.
Есть ли решение или обходной путь для такой проблемы?
Конечно, я мог бы продолжать использовать старое определение таблицы, используя строки для длины и ширины и т.п., и создать обновляемое представление для нового приложения, но мне кажется, что это неправильно.
Или я немного модифицирую приложение VB, у меня есть исходники, и сначала модифицирую модель данных, чтобы использовать поплавки для ширины, высоты и длины, но я предпочитаю оставить ее нетронутой.
Я бы надеялся, что обновляемые представления были ответом на такого рода проблемы.
ОБНОВЛЕНИЕ 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
80040e21
— это страшноеDB_E_ERRORSOCCURRED
, что означает, что что-то пошло не так, разберитесь сами. Обновление представления с помощью триггераINSTEAD OF
с использованием местоположения динамического курсора на стороне сервера возможно (я пробовал это в T-SQL), и это должно использоваться ADO . Чтобы узнать наверняка, попробуйте проследить оператор с помощью SQL Profiler, чтобы увидеть, что он на самом деле делает. Включите события ошибок для максимальной полезности. Если ваш набор записей находится на стороне клиента или отключен, проблема, вероятно, будет заключаться в том, что ADO знает, что вы не можете обновлять вычисляемые столбцы, но базовый сценарий должен быть возможен. - person Jeroen Mostert   schedule 12.12.2016