среда, 30 января 2013 г.

Получение данных из внешних БД


Рассмотрим пару вариантов работы с внешними БД.

Вариант 1: отобразить как список таблицу из внешней БД MS SQL, позволив пользователям работать с таблицей как со списком – просматривать, добавлять и удалять значения – строки.

Для этого нужно создать внешний тип контента в SP Designer:
ex1
ex2ex3

ex4
Выбрав “Подключиться с удостоверением пользователя”, мы сможем подключиться только к БД, расположенной на том же сервере, где находится БД SharePoint. При попытке подключения к какой-либо другой, получим ошибку, описанную вот тут:   http://www.spdoctor.net/Pages/message.aspx?name=login-failed-for-user-bdc
Как правило, подключение требуется к внешней БД, поэтому надо использовать 2й и 3ий варианты подключения. Эти варианты требуют идентификатора Secure Store – фактически это логин и пароль, в зашифрованном виде хранящиеся в специальной службе SharePoint. Создать Secure Store ID можно через “Центр Администрирования SharePoint” – “Управление приложениями-службами“. Там нужно найти “Приложение службы Secure Store” – называться оно может как угодно.
ВАЖНО: если таких служб 2 или более, обязательно выясните, какая из них используется веб-приложением “по умолчанию”. Сделать это можно здесь: “Центр администрирования - Сопоставления приложений-служб “. Именно её и нужно использовать для создания Secure Store ID.

ex5
По клику на “Создать” вызывается диалог, в котором создаются поля логина и пароля, затем можно задать эти логин и пароль, кликнув “Настроить” в блоке “Учётные данные”
Всё, SSID готов. Теперь можно указать его в поле “Идентификатор приложения SecureStore” и нам станут доступны таблицы внешнего источника данных. Для любой из них можно создать 5 типов операций:
ex6
Для того, чтобы отобразить содержимое таблицы как список – необходимо создать как минимум первые две операции. В создании нет ничего сложного – просто жмём Далее и Финиш.
Ещё один важный момент, без которого список не будет доступен – необходимо разрешить пользователям доступ к этому типу контента – это тоже делается в
“Центр Администрирования SharePoint” – “Управление приложениями-службами”, только теперь уже настраивается служба “Приложение-служба подключения к бизнес-данным”:
ex7
Как видим, этот вариант практически полностью (за исключением создания SecureStore) реализуем с помощью одного только SP Designer, однако имеет массу ограничений – нельзя таким образом работать с другими СУБД (например, Oracle), нельзя работать с объединением 2х и более таблиц – для этого нужно описывать модель работы с данными в коде, используя Visual Studio. В курсе 10175A SharePoint Application Development вторая лабораторная шестого урока посвящена именно такому созданию модели.

Вариант 2: доступ к внешней БД через powershell, работа с данными из БД как с объектами

Вот пример синхронизации списка SharePoint с данными из внешней БД Oracle.
Используется функция Get-DatabaseData, взято вот отсюда: http://technet.microsoft.com/ru-ru/magazine/hh855069.aspx
# Позволяет выполнять запросы к БД Oracle
function Get-DatabaseData {
[CmdletBinding()]
param (
  [string]$connectionString,
  [string]$query,
  [switch]$isSQLServer
)
if ($isSQLServer) {
  Write-Verbose 'in SQL Server mode'
  $connection = New-Object System.Data.SqlClient.SqlConnection
} else {
  Write-Verbose 'in OleDB mode'
  $connection = New-Object System.Data.OleDb.OleDbConnection
}
$connection.ConnectionString = $connectionString
#'Provider=OraOLEDB.Oracle;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host.host.ru)(PORT=1521)))(CONNECT_DATA=(SID=SOMESID)));User Id=USERID;Password=PASSWORD;'
#$connectionString = 'Provider=OraOLEDB.Oracle;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host.host.ru)(PORT=1521)))(CONNECT_DATA=(SID=SOMESID)));User Id=USERID;Password=PASSWORD;''
$command = $connection.CreateCommand()
$command.CommandText = $query
if ($isSQLServer) {
  $adapter = New-Object System.Data.SqlClient.SqlDataAdapter $command
} else {
  $adapter = New-Object System.Data.OleDb.OleDbDataAdapter $command
}
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataset)
return $dataset.Tables[0]
}
Источником данных может быть любая БД, разница только в строке подключения. Формат строки подключения для любой СУБД можно взять с http://connectionstrings.com/
Можно выполнять любые операции – INSERT, DELETE, CREATE и т.д. при наличии доступа к этой БД.
Ну и сам пример. Сравнивает данные о командах из таблицы БД с данными в списке “Alarm groups” по ID. Eсли команда переименована или создана, изменяет или создаёт новый элемент в списке. Если команда удалена – проверяет наличие связанных элементов из списка “Точки мониторинга” и при отсутствии связей удаляет элемент, иначе выдаёт оповещение:
$datarow = Get-DatabaseData -verbose -query "SELECT * FROM DUTY.group" -connectionString "Provider=OraOLEDB.Oracle;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host.host.ru)(PORT=1521)))(CONNECT_DATA=(SID=SOMESID)));User Id=USERID;Password=PASSWORD;"
$site = new-object Microsoft.SharePoint.SPSite("http://mysite")
$web = $site.OpenWeb("myweb")
$list = $web.Lists["Alarm groups"]
[Microsoft.SharePoint.SPListItemCollection]$list_items = [Microsoft.SharePoint.SPListItemCollection]$list.Items;
$message = "Запускаем процедуру синхронизации. Проверяем наличие новых или переименованных команд..."
log "Аварийные команды" $message
for( $i=1; $i -le $datarow[0];$i++) {
    $bool = 0
foreach( $list_item in $list_items ) {
    if ($list_item["ID0"] -eq $datarow[$i].Item(0)) {
  if ($datarow[$i].Item(1) -eq $list_item["Title"]) {
            $bool=1
   continue
   }
  else {
   $list_item["Title"] = $datarow[$i].Item(1)
            $list_item["_x0413__x041a__x0414_"] = "http://www.site.ru?groupId="+$datarow[$i].Item(0)+", "+$datarow[$i].Item(1)
   update $list_item
   $message = "Команда"+" "+$datarow[$i].Item(0)+" "+"переименована из"+" "+$list_item["Title"]+" в "+$datarow[$i].Item(1)
   log "Аварийные команды" $message
            $bool=1
            continue
   }
        }
}
    if (!($bool)) {
       $message = "Команда"+" "+$datarow[$i].Item(0)+" "+$datarow[$i].Item(1)+" "+"добавлена"
    log "Аварийные команды" $message
       $list_item = $list.Items.Add()
       $list_item["ID0"] = $datarow[$i].Item(0)
       $list_item["Title"] = $datarow[$i].Item(1)
       $list_item["_x0413__x041a__x0414_"] = "http://www.site.ru?groupId="+$datarow[$i].Item(0)+", "+$datarow[$i].Item(1)
       update $list_item
    }
}
$message = "Проверяем наличие удалённых команд"
log "Аварийные команды" $message
for($c = $list_items.Count - 1; $c -ge 0; $c--) {
    $bool = 0
    for( $i=1; $i -le $datarow[0];$i++) {
        if ( $list_items[$c]["ID0"] -eq $datarow[$i].Item(0)) {
            $bool=1
            continue
            }
        }
    if (!($bool)) {
    $title = $list_items[$c]["Title"]
    $coll_item_name = ""
$order_listx = $web.Lists["Точки мониторинга"]
    $queryx = new-object Microsoft.SharePoint.SPQuery
    $queryx.query = "<Where><Eq><FieldRef Name='_x0410__x0432__x0430__x0440__x04' /><Value Type='Lookup'>$title</Value></Eq></Where>"
$collectionx = $order_listx.GetItems( $queryx )
    if( $collectionx.count) {
        foreach( $coll_item in $collectionx){
            $title = $coll_item["Title"]
            $id = $coll_item["ID"]
            $coll_item_name = $coll_item_name+"<br>"+"<a href='http://mysite/myweb/Lists/PointsMonitoring/DispForm.aspx?ID=$id'>$title</a>"
            }
        $message = "ВНИМАНИЕ! Команда"+" "+$list_items[$c]["Title"]+" "+"была удалена из http://www.site.ru/DutyList, но не может быть удалена из списка Аварийных команд, т.к. остались ТМ со ссылкой на нее: "+$coll_item_name
        log "Аварийные команды" $message
        }
    else {
        $message = "Команда"+" "+$list_items[$c]["Title"]+" "+"была удалена из списка Аварийных команд"
        log "Аварийные команды" $message
        $list_items.Delete($c)
        }
    }
}
$list.Update()
$message = "Процедура синхронизации завершена"
log "Аварийные команды" $message

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

Отправить комментарий