2011-10-04 34 views
5

Đây có thể là một câu hỏi mới, nhưng tôi muốn tránh tràn bộ đệm. Tôi đọc rất nhiều dữ liệu từ sổ đăng ký sẽ được tải lên cơ sở dữ liệu SQL. Tôi đọc dữ liệu trong một vòng lặp và dữ liệu được chèn sau mỗi vòng lặp. Vấn đề của tôi là, theo cách này, nếu tôi đọc 20 khóa, và các giá trị dưới (số lượng các khóa khác nhau trên mọi máy tính), thì tôi phải kết nối với cơ sở dữ liệu SQL 20 lần. Tuy nhiên tôi phát hiện ra rằng, có một cách, để tạo ra một thủ tục lưu trữ, và vượt qua toàn bộ dữ liệu nó, và như vậy, máy chủ SQL sẽ đối phó với dữ liệu, và tôi phải kết nối chỉ một lần đến máy chủ SQL .Làm thế nào để xử lý một chuỗi lớn một cách chính xác?

Thật không may là tôi không biết cách xử lý một chuỗi lớn như vậy để tránh bất kỳ lỗi không mong muốn nào, như luồng bộ đệm. Vì vậy, câu hỏi của tôi là làm thế nào tôi nên khai báo chuỗi này?

Tôi có nên tạo chuỗi như char string[ 15000 ]; và nối các giá trị không? Hoặc là có một cách đơn giản hơn để làm điều này?

Cảm ơn!

+6

nó sẽ giúp đỡ nếu chúng ta biết mà ngôn ngữ lập trình bạn đang sử dụng, C hoặc C++ –

+0

@ Rob:. tôi đang sử dụng C, nhưng nếu ai đó cho thấy một C++ Ví dụ, sau đó tôi có thể sử dụng nó quá – kampi

+4

Tại sao không chỉ làm nhiều truy vấn chèn với một kết nối? – Dmitri

Trả lời

2

Chuỗi STL nên thực hiện công việc tốt hơn nhiều so với phương pháp bạn đã mô tả.

Bạn cũng sẽ cần xây dựng một số ngưỡng. Ví dụ, nếu chuỗi của bạn lớn hơn một byte lớn, nó sẽ đáng xem xét việc tạo các kết nối SQL khác nhau vì giao dịch của bạn sẽ quá dài.

+1

Cũng lưu ý rằng các chuỗi thư viện chuẩn C++ chỉ là C++ chứ không phải C. Thư viện đi kèm với triển khai C++ là thư viện chuẩn C++, _not_ STL. –

+0

Mooing Duck: khoai tây potàto, ít nhất trong trường hợp này ('std :: string'). 'STL' vẫn có thể được sử dụng một cách rõ ràng để nói đến phần đó của thư viện C++ Standard vốn được gọi là STL, và sau đó được tích hợp vào thư viện chuẩn. – rubenvb

0

Để thực hiện điều này đúng trong C, bạn cần cấp phát bộ nhớ động, sử dụng malloc hoặc một trong các hệ điều hành tương đương. Ý tưởng ở đây là để tìm ra bao nhiêu bộ nhớ bạn thực sự cần và sau đó phân bổ số tiền chính xác. Các chức năng đăng ký cung cấp nhiều cách khác nhau để bạn có thể xác định lượng bộ nhớ bạn cần cho mỗi lần đọc.

Sẽ phức tạp hơn một chút nếu bạn đang đọc nhiều giá trị và ghép chúng lại. Một cách tiếp cận sẽ là đọc từng giá trị vào một khối bộ nhớ được phân bổ riêng biệt, sau đó nối chúng vào một khối bộ nhớ mới khi bạn đã có tất cả chúng.

Tuy nhiên, có thể không cần thiết phải khắc phục nhiều sự cố này. Nếu bạn có thể nói "nếu dữ liệu lớn hơn X byte thì chương trình sẽ thất bại" thì bạn chỉ có thể tạo bộ đệm tĩnh như bạn đề xuất. Chỉ cần đảm bảo rằng bạn cung cấp các chức năng đăng ký và/hoặc chuỗi nối với kích thước chính xác cho phần còn lại của bộ đệm và kiểm tra lỗi, để nếu nó thất bại, nó không đúng.

Một lưu ý khác: char buf[15000]; là OK với điều kiện khai báo nằm trong phạm vi chương trình, nhưng nếu nó xuất hiện trong một hàm, bạn nên thêm thông số static. Bộ nhớ được cấp phát ngầm định trong một hàm theo mặc định được lấy từ ngăn xếp, do đó, một phân bổ lớn có khả năng thất bại và làm hỏng chương trình của bạn. (Mười lăm ngàn byte nên OK nhưng nó không phải là một thói quen tốt để có được vào.)

Ngoài ra, nó là một lợi thế để xác định một macro cho kích thước của bộ đệm của bạn, và sử dụng nó một cách nhất quán:

#define BUFFER_SIZE 15000 
char buf[BUFFER_SIZE]; 

để bạn có thể dễ dàng tăng kích thước của bộ đệm sau bằng cách sửa đổi một dòng.

+0

Tôi đã chỉnh sửa câu trả lời của bạn một chút. Tên macro thường là tất cả các chữ cái để chúng nổi bật. Và 'string' không phải là một tên rất tốt cho một đối tượng; Tôi đã đổi nó thành 'buf'. –

+0

@Keith, tôi đã sử dụng chuỗi [] vì đó là những gì OP được sử dụng trong câu hỏi của anh ấy, nhưng nó không thực sự quan trọng. Cảm ơn vì đã bắt được tên macro thấp hơn, tôi vẫn phải ngủ một nửa. –

0

Bạn có thể đọc (khóa, giá trị) từ một cơ quan đăng ký và lưu trữ chúng vào bộ đệm được phân phát trong khi có đủ không gian ở đó. Duy trì vị trí "ghi" trong bộ đệm. Bạn có thể sử dụng nó để kiểm tra xem có đủ không gian cho cặp khóa, giá trị mới trong bộ đệm hay không. Khi không còn khoảng trống cho cặp mới (khóa, giá trị) - thực hiện quy trình được lưu trữ và đặt lại vị trí "ghi" trong bộ đệm. Ở cuối vòng lặp "đọc khóa giá trị", hãy kiểm tra vị trí 'ghi' bộ đệm và thực hiện thủ tục đã lưu nếu nó lớn hơn 0. Bằng cách này, bạn sẽ giảm thiểu số lần bạn thực hiện quy trình được lưu trữ trên máy chủ

const int MAX_BUFFER_SIZE = 15000; 
char buffer[MAX_BUFFER_SIZE]; 
char buffer_pos = 0; // "write" position within the buffer. 

... 

// Retrieve key, value pairs and push them into the buffer. 
while(get_next_key_value(key, value)) { 
    post(key, value); 
} 

// Execute stored procedure if buffer is not empty. 
if(buffer_pos > 0) { 
    exec_stored_procedure(buffer); 
} 
... 

bool post(const char* key, const char* value) 
{ 
    int len = strlen(key) + strlen(value) + <length of separators>; 

    // Execute stored procedure if there is no space for new key/value pair. 
    if(len + buffer_pos >= MAX_BUFFER_SIZE) { 
    exec_stored_procedure(buffer); 
    buffer_pos = 0; // Reset "write" position. 
    } 

    // Copy key, value pair to the buffer if there is sufficient space. 
    if(len + buffer_pos < MAX_BUFFER_SIZE) { 
    <copy key, value to the buffer, starting from "write" position> 
    buffer_pos += len; // Adjust "write" position. 
    return true; 
    } 
    else { 
    return false; 
    } 
} 

bool exec_stored_procedure(const char* buf) 
{ 
    <connect to SQL database and execute stored procedure.> 
} 
Các vấn đề liên quan