MS PowerApps: как «залатать» таблицу SQL составным первичным ключом

#sql-server #powerapps #composite-primary-key #powerapps-canvas

#sql-сервер #powerapps #composite-primary-key #powerapps-canvas

Вопрос:

Я относительно новичок в MS PowerApps

У меня установлен SQL Server Express на локальном сервере со шлюзом для PowerApps

Моя таблица SQL Server имеет составной первичный ключ, он определяется как:

 CREATE TABLE [GFX_Information].[BusinessParnterAccess]
(
    [BpAccesID] [int] IDENTITY(1,1) NOT NULL,
    [CreatedDate] [datetime] NOT NULL,
    [UpdatedDate] [datetime] NOT NULL,
    [LastOperatorID] [int] NOT NULL,
    [CreateByID] [int] NOT NULL,
    [BPID] [int] NOT NULL,
    [AllowedOperatorID] [int] NOT NULL,
    [AccessFlag] [varchar](10) NULL,

    PRIMARY KEY CLUSTERED ([AllowedOperatorID] ASC, [BPID] ASC)
                WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                      IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                      ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [GFX_Information].[BusinessParnterAccess] 
    ADD DEFAULT (GETDATE()) FOR [CreatedDate]
GO

ALTER TABLE [GFX_Information].[BusinessParnterAccess] 
    ADD DEFAULT (GETDATE()) FOR [UpdatedDate]
GO
  

Я пытаюсь понять, как «исправить» новую запись.

В настоящее время, используя OnVisible событие, я создаю переменную для хранения последнего BpAccesID следующим образом

 UpdateContext ({varLastAccessID:First(SortByColumns('[GFX_Information].[BusinessParnterAccess]',"BpAccesID",Descending)).BpAccesID});
  

Я использую ручной набор значений для команды Patch для целей тестирования. Команда Patch

 Patch('[GFX_Information].[BusinessParnterAccess]',Defaults('[GFX_Information].[BusinessParnterAccess]')
    ,{BpAccesID:varLastAccessID 1
    ,CreatedDate: Now()
     ,UpdatedDate:Now()
     ,LastOperatorID:4
    ,CreateByID:4
        ,BPID:342
  ,AllowedOperatorID:4
  ,AccessFlag:"RW" });
  

Однако это не выдает ошибку, которую я могу обнаружить, и я не вижу, чего мне не хватает

Может ли кто-нибудь предложить какие-либо идеи, пожалуйста?

Комментарии:

1. Я не знаю, что такое «PowerApps», но поскольку BpAccesID столбец определен как IDENTITY , вы не должны указывать для него значение для новой строки. Сервер автоматически присвоит ему новое значение. Я бы попытался удалить этот текст: BpAccesID:varLastAccessID 1 , из вашего кода.

Ответ №1:

Я читал это, и это предложение основано на моих знаниях SQL Server и кратком чтении об исправлении. Это может вам помочь, а может и нет (прошу прощения). А также просто подтверждение: я предполагаю, что вопрос заключается в том, что «это не создает новую строку, и я не понимаю, почему?»

Я бы предположил, что ваша проблема BPAccessId связана с. Вы установили его как идентификатор: [BpAccesID] [int] IDENTITY(1,1) NOT NULL,

Однако вы явно вставляете в нее значение

 Patch('[GFX_Information].[BusinessParnterAccess]',Defaults('[GFX_Information].[BusinessParnterAccess]')
    ,{BpAccesID:varLastAccessID 1
  

Конечно, обычно вы не можете вставлять в столбец идентификаторов в SQL Server — вам нужно включить IDENTIY_INSERT (затем снова выключить после завершения). Кроме того, одна из причин, по которой столбцы IDENTITY PK должны всегда создавать новую строку с допустимым PK. Как описанный выше подход работает для параллелизма, например, два пользователя одновременно пытаются создать новую строку?

В любом случае, некоторые потенциальные решения у меня в голове. Еще раз, это основано только на моих знаниях SQL Server.

  • Измените инструкцию MS Powerapps для работы с идентификатором (я оставлю это на ваше усмотрение) — будь то эквивалент SET IDENTITY_INSERT table ON; или иное
  • Удалите свойство IDENTITY из BPAccessID (например, оставьте его как чистый int)
  • Сделайте первичный ключ составным из всех трех столбцов, например, AllowedOperatorID, BPID, BPAccessID
  • Сделайте BPAccessID первичным ключом, но некластерным, и создайте уникальный кластеризованный индекс для AllowedOperatorID, BPID

Для двух нижних, поскольку BPAccessID это все еще ИДЕНТИФИКАТОР, вам нужно разрешить SQL Server обрабатывать вычисление нового значения.

Если вы не используете внешние ключи для этой таблицы, то два нижних будут иметь аналогичные эффекты.

Однако, если есть внешние ключи, то нижний (некластеризованный PK и кластеризованный уникальный индекс на двух других), вероятно, наиболее близок к вашей текущей настройке (и на самом деле это то, что я обычно делаю в структуре таблиц, подобной вашей, независимо от PowerApps или другой обработки).

Комментарии:

1. Привет, спасибо. .. забавно, что я работал над этим днем. Я переключаю ed на нижний вариант (некластеризованный pk). Однако, когда не требуется время, я протестирую второй вариант включения столбца identity

2. Тот факт, что у вас есть комбинация других полей (в порядке, обратном таблице), наводит меня на мысль, что вы знаете, о чем говорите, о ПК и индексации. На данный момент ваша структура обеспечивает уникальность AllowedOperatorID, BPID (например, каждая их комбинация может появиться только один раз), которая будет потеряна, когда вы перейдете ко всем трем как PK. Если вы пойдете туда, вы также можете захотеть установить уникальное ограничение на два исходных поля (на ваше усмотрение).