Search  
Friday, May 25, 2012 ..:: Forum ::.. Register  Login
 Forum Minimize
Pentru a putea posta mesaje trebuie să vă înregistraţi.
Notă: Mesajele cu conţinut jignitor sau ilegal (inclusiv cereri de soft piratat) nu sunt acceptate şi vor fi şterse imediat .

Pentru a primi raspunsuri rapide si corecte, scrieti in mesaj ce intentionati sa faceti, ce mesaj de eroare primiti, in ce context si in urma caror actiuni. De asemenea, mentionati versiunea de FoxPro in care lucrati!
Dacă nu specificați versiunea, se consideră VFP 9.0 SP2.

SearchForum Home
  Visual FoxPro  Client/Server  SqlServer2008...
 SqlServer2008
 
 12/21/2011 5:21:22 PM
User is offlinemihaipopescump
13 posts


SqlServer2008
 (Romania)
VFP 9 Buna tuturor. Am o problema cumplita. Efectuarea unor calcule destul de complicate pe niste tabele de dimensiuni relativ mari (sute de mii, milioane de inregistrari) si inserarea rezultatelor in tabele dintr-o baza de date SQL Server 2008, prin intermediul ODBC. Am depasit etapa preluucrarii datelor (am rulat in cursoare readwrite si sunt multumit de timpii de executie), dar sunt foarte nemultumit de timpii de inserare in tabelele se pe serverul sql. Totul merge foarte lent, cel putin pe metodele clasice (append from sau insert). Am inteles ca incepand cu Sql Server 2008 sunt posibile inserari pe un numar mai mare de randuri (maximum 1000, din cate am citit) si ma gandeam ca as putea trimite datele utilizand un SqlExec. A lucrat cineva asa ceva? Sau, exista o alta metoda de a insera rapid datele pe astfel de tabele? Mentionez ca am facut teste pe MySql si timpii sunt sensibl mai buni, dar, din pacate, nu am libertatea de a alege. Si mai mentionez ca sunt tare necajit, ca m-am luptat pentru fiecare secunda in algoritm, iar acum nu-i dau de cap. Mii de multumiri celor care au citit acest mesaj si ar putea sa ma ajute. Si Sarbatori Fericite tuturor. Mihai.
 12/21/2011 6:43:27 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: SqlServer2008
 (N/A)
Cum faci acum inserarea?
Cate inregistrari? Ce lungime are o inregistrare?
Server sql express sau comercial?
Aplicatia vfp / vfp ide din care faci insertul e pe acceasi masina cu serverul sql?

Oricum, poti incerca urmatoarele variante:
SSIS de pe serverul sql.
Export in fisier text, csv sau cu alt delimitator, apoi import din serverul sql.
Linked server pe baza de date / tabela vfp si insert din linked server.
Remote view sau cursoradapter in vfp, cu batchupdatecount=100 sau mai mare, vezi prin incercari.
Cu sqlexec inseamna sa generezi cate o comanda insert pentru fiecare linie ce trebuie inserata pe server. Nu va fi mai rapida.


Daniel Buduru
 12/22/2011 11:52:52 AM
User is offlineneagu_laurentiu
101 posts
5th


Re: SqlServer2008
 (N/A)
Prelucreaza direct in SQL Server cu ajutorul procedurilor stocate si nu in VFP !
 12/22/2011 1:19:34 PM
User is offlinemihaipopescump
13 posts


Re: SqlServer2008
 (Romania)
Buna ziua domnule Buduru si multumesc pentru raspuns. Sunt informatii din trei tabele de detalii, insumate intr-un tabel centralizator. Clientii sunt prelucrati individual (cu conditii de calcul preluate din multe alte tabele), iar numarul de inregistrari pe tabela centralizatoare este, functie de client, de pana la 200.000 de randuri. In tabelele de detalii numarul de randuri este de pana la 500.000. Numarul de coloane este de 105 in centralizator si 30-50 in detalii, in majoritate varchar. Din pacate structurile sunt impuse si nu pot face nicio modificare la acest nivel. Aplicatia va rula pe acelasi calculator cu serverul de sql si se utilizeaza SQL Server 2008R2 Standard (64). * Din sugestiile oferite am testat doar Remote view, care merge la fel de lent indiferent de batchupdatecount. Toate inserarile trebuie sa fie comandate din aplicatia VFP, unde VFP este si el impus. Din ce-am citit, pot face inserari multiple in sql server 2008 pe o comanda de genul INSERT INTO TabelaDestinatie (NumeCampTabelaDestinatie) SELECT NumeCampTabelaSursa FROM TabelaSursa Si ma gandeam daca TabelaSursa ar putea fi tabela locala VFP, iar comanda sa fie data cu ajutorul sqlexec. Am testat, dar inserarea nu se efectueaza. Cam asta este. Multumesc de ajutor si scuze pentru neclaritatile din exprimare. Si pentru nepricepere.
 12/22/2011 1:32:16 PM
User is offlinemihaipopescump
13 posts


Re: SqlServer2008
 (Romania)
P.S. sqlexec functioneaza foarte bine daca tabela sursa este o tabela din baza de date de pe server. ** Problema este atunci cand sursa de date este in baza de date din VFP.
 12/22/2011 2:39:51 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: SqlServer2008
 (N/A)
Serverul sql si baza de date vfp sunt doua medii diferite, complet separate unul fata de celalalt. Prin urmare, nici o comanda in vreunul dintre medii, fie sql, fie vfp, nu poate include informatii din celalalt mediu.

Pentru a trimite infoematii dintr-un mediu in celalalt se creeaza o "punte de legatura" printr-u driver ODBC sau OLEDB.
Cu aceasta punte, din vfp informatiile pot fi transmise serverului prin remote view, cursoradapter sau sqlexec.
Remote view creeaza un cursor cu structura data de comanda select, apoi insereaza/ actualizeaza / sterge fiecare inregistrare in tabela server generand intern o comanda sqlexec.
Cursoradapterul este un wrapper pentru remote view, un obiect ce expune proprietatile cursorului si permite o gestionare a lor intr-o maniera OOP.
SQLEXEC executa o comanda pe servreul sql, prin conexiunea stabilita.
Pentru a insera intro tabela de pe server, se gebereaza o coamnda sqlexec de forma asta:
SQLEXEC(mConnectionHandle, [Insert into tabela (field1, field2) VALUES ('unu',1)])
sau, in forma parametrizata:
field1value='unu'
field2value=1
SQLEXEC(mConnectionHandle, [Insert into tabela (field1, field2) VALUES (?field1value,?field2value)])
Pentru a insera mai multe linii intr-o tabela de pe server se genereaza cate o comanda sqlexec pentru fiecare linie, fie generand textul in care se includ valorile, fie intr-o bucla in care se seteaza variabilele ce contin valorile, apoi se apeleaza acel sqlexec cu parametri.
Remote view si cursoradapter genereaza in mod automat aceste comenzi pentru fiecare linie din cursor.

O alta varianta este aceea de a face importul din sql server.
Se poate crea un linked server pe baza de date vfp, apoi insertul se face cu o comanda de forma:
Insert into tabela (field1, field2) Select field1, field2 from [linkedserver]...[tabela]
Linked server se creeaza utilizand acelasi driver odbc sau oledb, ca si in cazul conexiunii din vfp.

Poti insera si dintr-un select creat din OPENROWSET, comanda care creeaza un linked server ad-hoc.

O metoda mai rapida - si preferata - este bulk insert, care poate fi facuta tot de pe serverul sql
Aici gasesti explicatii detaliate: http://msdn.microsoft.com/en-us/library/ms188365.aspx
si aici: Se poate face insertul si cu openrowset, care creeaza un linked server ad-hoc.
Vezi aici mai multe:
http://msdn.microsoft.com/en-us/library/ms175915.aspx

Fisierul text il poti genera din vfp printr-un export in format csv, sdf, sau alt format delimited. Vezi comanda COPY TO ... TYPE SDF DELIMITED WITH ...

Conditia ca importul sa fie comandat din vfp se realizeaza simplu cu sqlexec. Poti crea o procedura stocata pe server pentru asta, sau poti pune intreaga comanda in sqlexec - cu respectarea limitelor pentru dimensiunea comenzii.

Daca dimensiunea datelor ce se importa este mare - numar de linii x lungime linie - trebuie sa te astepti la timpi mai lungi.

Timpul de executie creste din cauza logarii tranzactiilor pe server. Logarea fiecarei linii dureaza mai mult decat logarea unui set - si asta se controleaza prin dimensiunea batch-ului.

In final, subscriu la recomandarea lui Laurentiu: fa toate prelucrarile in serverul sql. Importa toate tabelele sursa - linked server sau openrowset - in tabele pe server, apoi fa toate procesarile pe server. Diferenta de viteza e de ordine de marime, daca algoritmul e adaptat serverului sql..
 


Daniel Buduru
 12/22/2011 3:01:23 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: SqlServer2008
 (N/A)
Alte exemple pentru bulk insert:
http://www.simple-talk.com/sql/learn-sql-server/bulk-inserts-via-tsql-in-sql-server/
blog.sqlauthority.com/2008/02/06/sql-server-import-csv-file-into-sql-server-using-bulk-insert-load-comma-delimited-file-into-sql-server/
http://sqlcat.com/sqlcat/b/technicalnotes/archive/2009/04/06/bulk-loading-data-into-a-table-with-concurrent-queries.aspx
http://beyondrelational.com/blogs/nakul/archive/2011/05/02/bcp-amp-bulk-inserts-underappreciated-features-of-microsoft-sql-server.aspx


Daniel Buduru
 12/27/2011 3:47:32 PM
User is offlinemihaipopescump
13 posts


Re: SqlServer2008
 (Romania)
N-am testat nimic pana astazi; totul se gaseste la beneficiar si au fost zile libere. In final am folosit Bulk Insert (comandat cu sqlexec din aplicatie), care merge foarte bine si mai ales suficient de repede. Multumesc, domnule Buduru, pentru o gramada de timp alocat acestei forme de ajutor. La fel si pentru sinteza trimisa. Mi-ar placea ca intr-o zi sa va pot intoarce acest serviciu. Multumesc si domnului Laurentiu; cu siguranta ca solutia recomandata de dumneavoastra este foarte eleganta, dar implementarea ei ar fi necesitat rescrierea unor mari parti din ce s-a dezvoltat pana acum. Acesta este motivul pentru care am cautat cu disperare o solutie "locala". Va doresc toate cele bune si un an nou minunat. Cu stima, Mihai Popescu.
 2/11/2012 9:55:55 AM
User is offlinemihaipopescump
13 posts


Re: SqlServer2008
 (Romania)
Din pacate revin cu o noua forma a aceleiasi probleme:

1. O aplicatie VFP ruleaza pe un SQLSERVER 2008 aflat pe acelasi calculator (server).
2. Exista un fel de replica replica a bazei de date (nu neaparat identica), pe un alt calculator (aflat la distanta), echipat cu aceeasi versiune SQLSERVER 2008,
si catre care este definita o legatura prin ODBC. De pe calculatorul (serverul) aflat la distanta nu poate fi definita nicio conexiune.

Discutam despre volume foarte mari de date (sute de mii, milioane de inregistrari, pe tabele cu pana la 100 de campuri)

Pe calculatorul local se fac prelucrari, apoi problema inserarii se rezolva cu o secventa de genul:

NumeFisierLocal1=FULLPATH(SYS(2003))+'\FisierLocal.txt'
select cursor_vfp_local copy to &NumeFisierLocal type delimited with "" with character ","
sqlexec(connX,"BULK INSERT dbo.FisierServerLocal FROM '&NumeFisierLocal' with (FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n')")

Problema apare atunci cand urmeaza sa se insereze acelasi pachet de date pe calculatorul aflat la distanta.
Acesta nu va gasi fisierul text si nu va executa Bulk Insert.

O sugestie?
V-as ramane indatorat.

Mihai Popescu.




 2/11/2012 10:31:14 AM
User is offlineGrigore Dolghin
3590 posts
www.class-software.eu
1st






Re: SqlServer2008
 (N/A)
Ai putea incerca sa definesti serverul remote ca fiind linked server in serverul local, iar dupa inserarea datelor din cursorul vfp in serverul local sa executi pe serverul local comenzi de genul Insert Into remoteserver.remotedb.table select * from localserver.localdb.table.

Grigore Dolghin
Visual FoxPro MVP 2006 - 2010
Class Software
My blog
 2/11/2012 11:40:20 AM
User is offlineDaniel Buduru
2335 posts
1st




Re: SqlServer2008
 (N/A)
 mihaipopescump wrote
Din pacate revin cu o noua forma a aceleiasi probleme:

1. O aplicatie VFP ruleaza pe un SQLSERVER 2008 aflat pe acelasi calculator (server).
2. Exista un fel de replica replica a bazei de date (nu neaparat identica), pe un alt calculator (aflat la distanta), echipat cu aceeasi versiune SQLSERVER 2008,
si catre care este definita o legatura prin ODBC. De pe calculatorul (serverul) aflat la distanta nu poate fi definita nicio conexiune.

Discutam despre volume foarte mari de date (sute de mii, milioane de inregistrari, pe tabele cu pana la 100 de campuri)

Pe calculatorul local se fac prelucrari, apoi problema inserarii se rezolva cu o secventa de genul:

NumeFisierLocal1=FULLPATH(SYS(2003))+'\FisierLocal.txt'
select cursor_vfp_local copy to &NumeFisierLocal type delimited with "" with character ","
sqlexec(connX,"BULK INSERT dbo.FisierServerLocal FROM '&NumeFisierLocal' with (FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n')")

Problema apare atunci cand urmeaza sa se insereze acelasi pachet de date pe calculatorul aflat la distanta.
Acesta nu va gasi fisierul text si nu va executa Bulk Insert.

O sugestie?
V-as ramane indatorat.

Mihai Popescu.


Operatia asta se face o singura data? La trecerea bazei de date dbf pe serverul SQL?

Daniel Buduru
 2/11/2012 1:36:52 PM
User is offlinemihaipopescump
13 posts


Re: SqlServer2008
 (Romania)
Datele sunt prelucrate periodic si inregistrate in tabelele de pe serverul local.
Transferul pe serverul aflat la distanta se face din aplicatie, in urma unor validari, tot periodic, dar pentru alte intervale de timp decat cele de la prelucrare.
Din pacate nu mai pot utiliza modelul de cod de mai sus (care s-a dovedit foarte rapid - si va multumesc inca o data pentru sfatul de a folosi 'bulk insert'), iar cu linked server n-am lucrat.
De dimineata ma tot lupt sa gasesc o varianta de lucru utilizand OPENROWSET, dar deocamdata n-am reusit nimic.
 2/11/2012 4:36:10 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: SqlServer2008
 (N/A)
Dacadatele sunt aduse local, prelucrate in vfp si urcate inapoi pe server, aplicatia e nascuta moarta. Prelucrarile se fac pe server, nu in vfp.
Timpul necesar pentru trecerea algoritmului de prelucrare fin vfp in T-Sql e mult mai mic decat cel necesar pentru rezolvarea problemelor care apar datorita acestui mod de lucru.

Procedura pentru crearea unui linked server mssql e aici:
http://msdn.microsoft.com/en-us/library/ff772782.aspx
La @server= se pune acelasi lucru care exista in stringul de conectare (ce ai la server=. ..) cu care realizezi acum conexiunea la acel server.


Daniel Buduru
 2/11/2012 5:11:33 PM
User is offlinemihaipopescump
13 posts


Re: SqlServer2008
 (Romania)
Multumesc pentru raspuns, mai ales ca-i sambata.
Din pacate nu mai este timp aproape pentru nimic.

Ultima prelucrare, cea de validare si in urma careia datele sunt expediate la distanta este scrisa deja pe serverul local.
Inregistrarile care trebuiesc trimise sunt deja marcate cu identificatorul de validare si se afla pe sqlserver. Incercam sa folosesc variante cunoscute, ca sa evit (in criza de timp) notiuni cu care n-am lucrat, cum ar fi linked server

Practic trebuie sa transfer niste volume de date de pe un server sql pe un alt server sql, aflat la distanta si cu care exista o legatura pe odbc.
Pot evita asadar trimiterea datelor din baza de date VFP. Practic, la acest moment VFP nu mai conteaza decat in masura in care as putea (cu un sqlexec, eventual) sa comand trimiterea datelor.

O sa incerc sa fac linked si sa inserez pe metoda propusa de dl. Dolghin.

Multumesc pentru tot sprijinul.
Mihai
 2/11/2012 5:58:12 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: SqlServer2008
 (N/A)
Un script pentru crearea unui linked server sql express 2008.
Inlocuieste valorile in rosu cu valorile tale, apoi ruleaza scriptul pe serverul local.


USE [master]
GO

/****** Object:  LinkedServer [RSQLX10]    Script Date: 11.02.2012 18:51:19 ******/
EXEC master.dbo.sp_dropserver @server=N'RSQLX10', @droplogins='droplogins'
GO

/****** Object:  LinkedServer [RSQLX10]    Script Date: 11.02.2012 18:51:19 ******/
EXEC master.dbo.sp_addlinkedserver @server = N'RSQLX10', @srvproduct=N'SQLOLEDB', @provider=N'SQLNCLI', @datasrc=N'tcp:192.168.100.15,12464'
 /* For security reasons the linked server remote logins password is changed with ######## */
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'RSQLX10',@useself=N'False',@locallogin=NULL,@rmtuser=N'userul_declarat_pe_serverul_remote',@rmtpassword='#########'

GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'collation compatible', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'data access', @optvalue=N'true'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'dist', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'pub', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'rpc', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'rpc out', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'sub', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'connect timeout', @optvalue=N'0'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'collation name', @optvalue=null
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'lazy schema validation', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'query timeout', @optvalue=N'0'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'use remote collation', @optvalue=N'true'
GO

EXEC master.dbo.sp_serveroption @server=N'RSQLX10', @optname=N'remote proc transaction promotion', @optvalue=N'true'
GO




Daniel Buduru
 2/11/2012 7:28:47 PM
User is offlinemihaipopescump
13 posts


Re: SqlServer2008
 (Romania)
Multumesc pentru raspuns, domnule Buduru.
O sa incerc abia maine, cand o sa am acces la serverul la distanta.
 2/12/2012 4:53:04 PM
User is offlinevaly.m
227 posts
4th


Re: SqlServer2008
 (N/A)
Hmmm...
Sa incep... Dupa multe cautari si cercetari, am ajuns "pe mana" lui Dan Buduru, care, din start, la problema pe care i-am detaliat-o asa cum am stiut de bine, mi-a spus : "Linked Server".
Mi-a aratat pas cu pas cum sa fac, ce sa fac, + multe detalii despre cum sa fac transferul de date. Astfel in cateva zile (2,3) am pus la punct, prin ajutorul indicatiilor lui, un transfer de date din free table, ale unei aplicatii pe FP2.6, pe un Server SQL 2005, prin Linked Server "fabricat" pe statiile locale unde se afla aplicatiile FP2.6, unde am instalat SSQL2008Express. Am creat proceduri stocate pe fiecare server expres, intr-o baza de date prin care aduc datele din free tables. Pe serverul comercial, unde se centralizeaza datele am creat linked server catre serverele express. Am creat joburi pe serverul comercial, care executa proceduri stocate din baza de date, proceduri care nu fac altceva decat sa execute procedurile stocate din linked server si sa preia apoi datele din serverele linkate in serverul comercial! Si astfel eu nu fac nimic, face serverul sql treaba mea! Plus tot felul de proceduri stocate pentru rapoarte, decl 394, etc.. si las serverul sa faca treaba, eu trimit doar comanda din vfp sa execut procedura stocata! ;)
A fost cea mai buna idee pentru situatia mea, similara cu cea discutata aici.
Asa ca spor la treaba.

Valy Maties - Beginner programmer
  Visual FoxPro  Client/Server  SqlServer2008...

Search  Forum Home         

 Google Ads Minimize

    

Copyright 2002-2010 Profox   Terms Of Use  Privacy Statement