Обновляемое представление дает ошибку времени выполнения в Visual Basic
Я пытаюсь преобразовать старую программу Visual Basic, которая использует устаревшие таблицы базы данных, в более современную и надежную реализацию. Он использует много varchars, когда должен был использовать float, чтобы привести конкретный пример, он делает код очень трудным для чтения, так как необходимо много преобразований из float в string и reverse, которых я хочу избежать в новом приложении)
Чтобы сохранить нисходящую совместимость, я создаю обновляемые представления для моих новых таблиц, чтобы старое приложение в 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, который является названием представления, которое я показал выше.
Error Ошибка времени выполнения, которую я получаю, обычно равна -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
1 ответ
"Обновляемое" представление является неправильным. Представление ничего не хранит. Столбцы с псевдонимами возвращают измененный вид данных в таблице.
В вашем примере у вас есть два возможных пути кода для одного значения (ноль или не ноль). Вы пытаетесь отправить код обратно по одному из путей кода, чтобы получить базовое значение. Если, например, вы отправили "по пути", как бы SQL узнал, должно ли это быть литералом или пустым значением, которое было заменено.
По этой причине вы не можете обновлять столбцы с выражением. Выражение эффективно доступно только для чтения в представлении.