Запрос питания Excel, обработка ошибок для резервного подключения / источник данных OleDb

У меня есть PowerQuery, подключенный к источнику данных DB2, но из-за некоторой балансировки нагрузки сервер БД периодически меняется (IP также изменяется), у меня нет возможности заранее узнать, какой источник данных (IP) я должен использовать, пока я не попробуйте и убедитесь, что он выдает ошибки, затем я должен использовать другой, я искал в Google для обработки ошибок в PowerQuery и нашел несколько примеров обработки ошибок, но эти примеры не применимы к моему случаю, большинство из них обрабатывали ошибки ПОСЛЕ подключения был сделан или предотвращал ошибки в недостающих столбцах или файлах, которые не были найдены, я попытался скорректировать примеры для своего случая, но не смог.

Я хочу просто попробовать один IP-адрес, а если он не удастся, использовать другой.

let

//fParametros("ParamQuery",1) is the "standard" Server/Ip address (provider=IBMDADB2.IBMDBCL1;data source=CP3;location=pn8us7ldbcp3.us.mycompany.com:5912)

dbSource = fParametros("ParamQuery",1),

//fParametros("ParamQuery",5) is the "Alternate" Server/Ip address (provider=IBMDADB2.IBMDBCL1;data source=CP3;location=pn8us7ldbcp3h.us.mycompany.com:5912)

AltdbSource = fParametros("ParamQuery",5),
pOrden = Text.From(fParametros("ParamQuery",2)),

//Create the query
dbQuery = "SELECT SAPCP3.vbak.VBELN SO , SAPCP3.vbap.posnr PoLine , SAPCP3.vbep.ETENR Sch_Line , SAPCP3.vbap.matnr Part_Number,SAPCP3.makt.maktx Description,SAPCP3.vbap.kwmeng Qty ,SAPCP3.vbep.BMENG Conf_qty ,SAPCP3.vbap.vrkme UOM ,SAPCP3.vbap.netpr SalesPrice ,SAPCP3.vbap.kpein LotSize FROM SAPCP3.vbak JOIN SAPCP3.vbap ON SAPCP3.VBAp.VBELN = SAPCP3.VBAK.VBELN JOIN SAPCP3.vbep ON SAPCP3.vbep.vbeln = SAPCP3.vbak.vbeln AND SAPCP3.vbap.posnr  = SAPCP3.vbep.posnr JOIN sapcp3.makt ON sapcp3.vbap.matnr=sapcp3.makt.matnr WHERE SAPCP3.VBAK.VKORG = '4000' AND (SAPCP3.vbep.edatu >= '20190701') AND SAPCP3.vbak.VBELN ="& pOrden & " ORDER BY SAPCP3.vbak.VBELN",

//Get the data
Source = OleDb.DataSource(dbSource, [Query=dbQuery]),

//Failed Attempt to handle the error:    

TestForError= try Source,

//next line does not work, I get error saying Source is already defined/declared
Source = if TestForError[HasError] then OleDb.DataSource(AltdbSource, [Query=dbQuery]) else OleDb.DataSource(dbSource, [Query=dbQuery])

in

Source

Я также пробовал следующее:

.
.
.

//Get the data
Source = OleDb.DataSource(dbSource, [Query=dbQuery]),

//Failed Attempt to handle the error:
TestForError= try Source,

Output = if TestForError[HasError] then OleDb.DataSource(AltdbSource, [Query=dbQuery]) else OleDb.DataSource(dbSource, [Query=dbQuery])

in

Output


//This last part works if the dbSource is correct, but if it is not it doesnt catch the error and gives me the Connection error shown below:

DataSource.Error: OLE DB: SQL30081N Обнаружена ошибка связи. Используемый протокол связи: «TCP / IP». Используемый коммуникационный API: «РОЗЕТКИ». Местоположение, в котором была обнаружена ошибка: «172.16.0.1». Функция связи, обнаруживающая ошибку: «подключиться». Код (ы) ошибок протокола: «10061», «», «». SQLSTATE = 08001 Подробности: DataSourceKind = OleDb DataSourcePath = data source = CP3; location = pn8us7ldbcp3.us.mycompany.com: 5912; provider = IBMDADB2.IBMDBCL1 Сообщение = SQL30081N Обнаружена ошибка связи. Используемый протокол связи: «TCP / IP». Используемый коммуникационный API: «РОЗЕТКИ». Местоположение, в котором была обнаружена ошибка: «172.16.0.1». Функция связи, обнаруживающая ошибку: «подключиться». Код (ы) ошибок протокола: «10061», «», «». SQLSTATE = 08001 Код ошибки = -2147467259

Я хочу подключиться к dbSource (172.16.0.1), и если это невозможно, подключитесь к AltdbSource (172.16.0.2)

В настоящее время у меня есть 2 идентичных листа Excel, и пользователю нужно открыть один или другой, если он получит ошибку подключения, я хочу, чтобы это изменилось автоматически.


person arana    schedule 22.11.2019    source источник
comment
Если у вас кластерный Db2, то ваши приложения должны подключаться к служебному адресу, а не к отдельным кластерным серверам Db2. Поговорите со своим администратором баз данных, чтобы получить правильный плавающий IP-адрес или DNS-имя службы для вашего кластера. Идея состоит в том, что база данных меняется между именами хостов, которые приложения просто повторно подключают к тому же ip-адресу / имени службы. Это самый простой способ справиться с такими вещами.   -  person mao    schedule 22.11.2019
comment
Спасибо за ваш комментарий, я уже пробовал это, но это действительно обременительный процесс, чтобы получить от них что-либо, они с трудом согласились предоставить нам права доступа, они предпочитают обрабатывать все запросы самостоятельно (с нас тоже, конечно), они не очень довольны тем, что у нас есть доступ для чтения, и хотели бы, чтобы мы делали все через SAP GUI (это наши поставщики услуг, подразделение нашей собственной компании), поэтому я все равно хотел бы знать, есть ли другой способ сделать это.   -  person arana    schedule 22.11.2019


Ответы (1)


Я предполагаю, что TestForError = try OleDb.DataSource(BadSource) не работает, потому что OleDb.DataSource(...) возвращает значение таблицы, а только вызывает ошибку при попытке перечислить строки.

Что, если вы измените TestForError для перехода к первой строке, если она существует:

TestForError= try Source{0}?,

Если это по-прежнему не работает, попробуйте выполнить индексацию в ячейку таблицы в первой строке.

person Carl Walsh    schedule 22.11.2019
comment
Не уверен, что я вас понял, dbQuery уже выбирает несколько записей, если источник не в порядке, я даже не могу подключиться к нему, поэтому он ДОЛЖЕН вызвать ошибку. - person arana; 26.11.2019
comment
Табличные значения могут быть ленивыми, т.е. они фактически не запускают SQL-запрос, пока какой-либо код не проверит столбцы или не начнет перечисление строк. Я не помню реализации, но OleDb может сначала открыть соединение, а потом запустить SQL. В качестве действительно простого примера лени представьте, что вы создаете Concat, объединив простой список {1} с List.Generate (), который ошибается при перечислении первого значения. Concat - допустимое значение списка, но значения внутри еще не оценены. Вы должны иметь возможность запустить Concat {0}, чтобы получить 1, но затем перечисление второго значения Concat {1} приведет к ошибке. - person Carl Walsh; 26.11.2019
comment
Я понимаю, что вы имеете в виду, говоря о лени, но в этом случае соединение не может быть выполнено с неправильным источником базы данных, поэтому ни один запрос, который должен быть запущен, не является даже открытым соединением. (первая строка НИКОГДА не будет существовать, так как я не могу подключиться к БД) - person arana; 26.11.2019