5 / 5 / 5
Регистрация: 17.12.2013
Сообщений: 200
1

Сборка для импорта данных с GoogleDocs в SQL server

17.01.2017, 16:44. Показов 1058. Ответов 2
Метки нет (Все метки)

Добрый день
Задача - заливать данные с GoogleDocs в таблицу SQL Server
Для этого решено было пойти путем CLR
Вот код:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
 
// For the SQL Server integration
using Microsoft.SqlServer.Server;
 
// Other things we need for WebRequest
using System.Net;
using System.IO;
 
namespace SqlWebRequestGoogleDocsToSQL
{
    public class Functions
    { // Function to return a web URL as a string value.
        [Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
        public static void GET(SqlString uri, SqlString username, SqlString passwd, String Table_Name, String Connection_String)
        {
            // The SqlPipe is how we send data back to the caller
            SqlPipe pipe = SqlContext.Pipe;
            String document;
            DataTable csvFileData;
 
            // Set up the request, including authentication
            WebRequest req = WebRequest.Create(Convert.ToString(uri));
            if (Convert.ToString(username) != null & Convert.ToString(username) != "")
            {
                req.Credentials = new NetworkCredential(
                    Convert.ToString(username),
                    Convert.ToString(passwd));
            }
            ((HttpWebRequest)req).UserAgent = "CLR web client on SQL Server";
 
            // Fire off the request and retrieve the response.
            // We'll put the response in the string variable "document".
            WebResponse resp = req.GetResponse();
            req.Timeout = 50000;
            Stream dataStream = resp.GetResponseStream();
            StreamReader rdr = new StreamReader(dataStream);
            // document = (String)rdr.ReadToEnd();
            document = (String)rdr.ReadToEnd();
            csvFileData = convertStringToDataTable(document);
            // Close up everything...
 
            rdr.Close();
            dataStream.Close();
            resp.Close();
 
            // .. and return the output to the caller.
            // return (document);
            // System.IO.File.WriteAllText(@"C:\temp\WriteText.txt", document);
 
            InsertDataIntoSQLServerUsingSQLBulkCopy(csvFileData, Table_Name, Connection_String);
        }
 
 
        public static DataTable convertStringToDataTable(string data)
        {
            DataTable dataTable = new DataTable();
            bool columnsAdded = false;
            foreach (string row in data.Split('$'))
            {
                DataRow dataRow = dataTable.NewRow();
                foreach (string cell in row.Split(','))
                {
                    string[] keyValue = cell.Split('~');
                    if (!columnsAdded)
                    {
                        DataColumn dataColumn = new DataColumn(keyValue[0]);
                        dataTable.Columns.Add(dataColumn);
                    }
                    dataRow[keyValue[0]] = keyValue[1];
                }
                columnsAdded = true;
                dataTable.Rows.Add(dataRow);
            }
            return dataTable;
        }
 
        static void InsertDataIntoSQLServerUsingSQLBulkCopy(DataTable csvFileData, String Table_Name, String Connection_String)
        {
            using (SqlConnection dbConnection = new SqlConnection(Connection_String))
            {
                dbConnection.Open();
                using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                {
                    s.DestinationTableName = Table_Name;
                    foreach (var column in csvFileData.Columns)
                        s.ColumnMappings.Add(column.ToString(), column.ToString());
                    s.WriteToServer(csvFileData);
                }
            }
        }
 
    }
}


В C# у меня знания очень поверхностные
Но поиски в инете дали такой вот результат
Есть три метода.
Один получает параметры от SQL Server, включая ссылку, выгружает результат в String переменную document.
Второй преобразует этот String document в DataTable.
Третий записывает значения DataTable в таблицу SQL Server

В SQL Server подключаю эту сборку и создаю процедуру:
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ALTER DATABASE [DB] SET TRUSTWORTHY ON
 
 
-- Подключаем сборку импорта с GD
USE [DB]
GO
CREATE ASSEMBLY [SqlWebRequestGoogleDocsToSQL]
FROM 'C:\DLL\SqlWebRequestGoogleDocsToSQL.dll'
WITH PERMISSION_SET=UNSAFE;
GO
 
-- Создаем процедуру имопрта данных с GD и запись результата  в таблицу SQL Server 
USE [DB]
GO
IF OBJECT_ID('pr_get_webrequest_google_docs_to_sql') IS NOT NULL DROP PROCEDURE [pr_get_webrequest_google_docs_to_sql]
GO
CREATE PROCEDURE [dbo].[pr_get_webrequest_google_docs_to_sql](
     @uri                 nvarchar(MAX),
     @USER                nvarchar(255)=NULL,
     @passwd              nvarchar(255)=NULL,
     @TABLE_NAME          nvarchar(50)=NULL,
     @Connection_String   nvarchar(255)=NULL
)
AS
EXTERNAL NAME [SqlWebRequestGoogleDocsToSQL].[SqlWebRequestGoogleDocsToSQL.Functions].[GET];


Выполняю таким образом:
Кликните здесь для просмотра всего текста
SQL
1
2
3
DECLARE @URL NCHAR(300) = 'https://docs.google.com/spreadsheets/d/1E5nfOKgRawXBDL6qhBZPwSj3EvY/pub?output=csv'
 
EXEC [DB].[dbo].[pr_get_webrequest_google_docs_to_sql] @URL, DEFAULT, DEFAULT, 'Планы', 'Data Source=;Initial Catalog=DB;User ID=; Password='


На выходе такая ошибка:

сообщение: 6522, уровень: 16, состояние: 1, процедура: pr_get_webrequest_google_docs_to_sql, строка: 0 [строка начала пакета: 10]
Произошла ошибка .NET Framework во время выполнения определяемой пользователем подпрограммы или агрегатной функции "pr_get_webrequest_google_docs_to_sql":
System.IndexOutOfRangeException: Индекс находился вне границ массива.
System.IndexOutOfRangeException:
в SqlWebRequestGoogleDocsToSQL.Functions.convertStri ngToDataTable(String data)
в SqlWebRequestGoogleDocsToSQL.Functions.GET(SqlStri ng uri, SqlString username, SqlString passwd, String Table_Name, String Connection_String)
CSV с гугл дока получаю такой структуры . Разделитель полей - запятая. Что выступает разделителем строк - не понятно..

Помогите пожалуйста разобраться
Может сам код можно как-то оптимизировать?..
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2017, 16:44
Ответы с готовыми решениями:

Настройка SQL Server 2008 для работы с SQL Server Management Studio
Доброго времени суток. Подскажите пожалуйста, что нужно сделать для того, чтобы SQL Server...

Макрос для импорта данных из excel в sql
Вообщем проблема заключается в том что нужен макрос для импорта определенных столбцов из ЭКСЕЛЬ...

Програмный метод !импорта! таблиц через ODBC(SQL Server 2000)
Собственно, сабж. Может есть у кого-нить ссылочка али примерчик какой?

Как средствами джавы реализовать просмотр базы данных Access, SQL Server, SQL Server Compact и запись в нее?
---

2
.NET senior
440 / 358 / 137
Регистрация: 23.09.2016
Сообщений: 980
17.01.2017, 20:33 2
googlogmob, попробуйте добавить в решение с Вашей сборкой проект юнит-тестов. Добавьте к этому проекту ссылку на сборку и вызовите метод в тесте с нужными параметрами - и сможете отслеживать процесс выполнения кода пошагово в режиме отладки. Это позволит быстро определить место возникновения проблемы и исправить её.
0
5 / 5 / 5
Регистрация: 17.12.2013
Сообщений: 200
20.01.2017, 00:12  [ТС] 3
Реализовано через R:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
EXEC sp_configure  'external scripts enabled', 1  
Reconfigure  WITH override
 
DECLARE @GoogleSheetURL nvarchar(500) = 
'OutputDataSet <- read.csv(file = "https://docs.google.com/spreadsheets/d/128qCX1YtvsHr4hERruFx6Ykn72qRkpRGH5brFULl7SY/pub?gid=0&single=true&output=csv, 
header = TRUE, sep = ",", encoding = "UTF-8", stringsAsFactors = FALSE)'
 
EXEC sp_execute_external_script  
  @LANGUAGE =N'R',    
  @script = @GoogleSheetURL,      
  @input_data_1 = N'   ;'    
  WITH RESULT SETS (([Дата] DATE,[Отдела] nvarchar(20),[Продукт] nvarchar(20),[Продавец] nvarchar(20),[Выставлено_шт] INT,[Оплачено_шт] INT,[Выставлено] INT,[Оплачено] INT ));    
GO
Дополнительно нужно разрешить два правила в настройках брандмауэра(на скрине)
Для SQL Server 2016
Миниатюры
Сборка для импорта данных с GoogleDocs  в SQL server  
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.01.2017, 00:12
Помогаю со студенческими работами здесь

Создать в SQL Server базу данных для хранения данных
В общем пригласили меня на собеседования, дали тестовое задания, мог бы помочь кто? Как с этим...

Тип данных edit для заполнения в sql server
Возникла проблема следующего рода, вводятся данные в edit1 и edit2, строка заполнения adr:='INSERT...

SQL Server для получения данных в своей программе
Помогите мне... У меня есть программа, ее надо переделать что бы она использовала SQL Server для...

[Microsoft][ODBC SQL Server Driver][SQL Server]Login failed- User: Reason: Not defined as a valid user of a trusted SQL Server connection
Login failed- User: Reason: Not defined as a valid user of a trusted SQL Server connection Вот...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru