DATALENGTH (Transact-SQL)
Эта функция возвращает число байтов, использованных для представления выражения.
Чтобы получить количество символов в строковом выражении, используйте функцию LEN.
Синтаксис
DATALENGTH ( expression )
Ссылки на описание синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий, см. в статье Документация по предыдущим версиям.
Аргументы
expression
Выражение любого типа данных.
Типы возвращаемых данных
bigint, если expression имеет тип данных nvarchar(max), varbinary(max) или varchar(max); в противном случае int.
Примечания
Функция DATALENGTH особенно полезна при использовании с типами данных переменной длины, как показано ниже.
Для значения NULL функция DATALENGTH возвращает NULL.
Уровни совместимости могут повлиять на возвращаемые значения. Дополнительные сведения об уровнях совместимости см. в статье Уровень совместимости ALTER DATABASE (Transact-SQL).
Функция LEN возвращает количество символов, закодированных в определенное строковое выражение, а функция DATALENGTH — размер данных в байтах для определенного строкового выражения. Эти выходные данные могут быть разными в зависимости от типа данных и типа кодировки, используемой в столбце. Дополнительные сведения об отличиях типов кодировок, используемых для хранения данных, см. в статье Collation and Unicode Support (Поддержка параметров сортировки и Юникода).
Примеры
В следующем примере находится длина столбца Name в таблице Product :
USE AdventureWorks2022 GO SELECT length = DATALENGTH(EnglishProductName), EnglishProductName FROM dbo.DimProduct ORDER BY EnglishProductName; GO
Скачивание бинарных данных из БД MS SQL средствами php
Добрый день всем. Подсобите пожалуйста с вопросом, который пока не могу решить, поиск в интернете особо не дал ответа. Итак есть файлы, которые хранятся в БД MS SQL, в бинарном виде (поле blob). Задача простая, вывести для каждой статьи соответствующее приложение/приложения средствами php. Итак код, который дает мне какой-то результат.
try < $db = new PDO("odbc:Driver=;Server=SERVER;Database=mydb; Uid=user;Pwd=1admiN; charset=UTF-8"); $sql = $db->query("SELECT TOP 1 id, name, ext, file FROM blob_files"); $row = $sql->fetchAll(PDO::FETCH_ASSOC); > catch (PDOExeption $e) < print "error". $e->getMessage(). "
"; die(); > foreach ($row as $key => $value)
Когда файл скачивается (размер вроде соответствует), но при открытии файла, например .doc, в ворде отображаются сначала пустые первые 5 строк, а потом весь бинарный код, в виде текста. Нашел в сети пример где вместо функции fopen() , используют функцию file_put_content() . Этой функцией получилось избавиться от первых пяти пустых строк, но увы файл также открывается как текст. Также пробовал все режимы для fopen() , не помогло. Также на просторах вычитал, что MS SQL передает бинарные данные в кодировке ANSI и если надо передавать данные для UTF8, то писать при подключении надо в какой кодировке следует открывать соединение, но я в этом не разобрался, тем более, что название файлов на кириллице на скачку дает корректно, при этом если сделать var_dump($row) — результат выборки данных из БД, то там где русскоязычные названии, рисует знаки вопроса в ромбе )). Короче вокруг одни вопросы, а ответа пока не видно, хотя задачка тревиальная. Скажу что проделывая дома, то же самое на MySQL, все работает как надо, в примитивном виде и даже если задать на выборку не 1 строки а 5, то скачивает все 5 файлов, а вот такой фокус на MS SQL не проходит. поправка Есть такое дело недоглядел, когда сюда переносил по памяти. Но не поставленная в примере кавычка закрывающая в запросе, сути не меняет. Итак, если я ставлю (пишу с телефона, поэтому извиняйте)
foreach ($row as $key=>$value) < $filename = $value['Name']; $fp = fopen($filename, 'wb') or die("Ошибка!"); $file = fwrite($fp, $value['File']) or die ('Error'); header ('Content-disposition: attachment; filename=$filename'); header ('Content-type: application/x-force-download;'); echo $value['File']; >
то он мне выдает файл с расширением, как положено, но первые 5 строк пустые. Если я пишу тот же цикл, только убираю два хедера внутри и ставлю header после цикла
header ('Location: '.$filename); exit();
то он мне выдает файл без пустых строк. Но в том и другом случае внутри в виде текста бинарный код этого файла.
Журналы (logs) в MySQL
В MySQL на данный момент существуют 4 вида журнала (лога) и при достаточно серьёзной работе с базами на MySQL необходимо за ними следить. Например, бинарный лог у нас за сутки набирает около гигабайта, а размер жёсткого диска на сервере ограничен и за ними надо следить. Однако следить следует не только за бинарным логом, так как логи (журналы) в MySQL могут принести немалую пользу.
Итак, какие логи ведёт MySQL? Это:
1. бинарный лог (binary log)
2. лог ошибок (error log)
3. лог медленный запросов (slow query log)
4. лог запросов (general query log)
5. лог репликаций (relay log)
Каждый из них по-своему полезен.
Бинарный лог
В первую очередь полезен с точки зрения репликаций. Можно его бэкапить, можно использовать для восстановления данных на более точное время при использовании бэкапов. Лог содержит все команды изменений базы данных, выборки (select, show) не сохраняет, для таблиц, поддерживающих транзакции (BDB, InnoDB) запись в лог выполняется только после выполнения команды COMMIT . Для лога можно указывать список баз данных, которые надо логировать и список баз данных, которые не надо логировать. В более ранних версиях вместо бинарного лога использовался лог обновлений. Использование бинарного лога снижает производительность базы данных, однако его польза настолько велика, что крайне не рекомендуется его отключать. Рекомендуется защищать бинарный лог паролем, так как он может данные также о паролях пользователей. При достижении максимально разрешённого размера (1 гиг по умолчанию) создаётся следующий файл. Каждый новый файл имеет порядковый номер после имени.
Содержание бинарного лога можно посмотреть с помощью утилиты mysqlbinlog.
Основные настройки в my.cnf
Местоположение лога:
log_bin = /var/log/mysql/mysql-bin.log
Максимальный размер, минимум 4096 байт, по умолчанию 1073741824 байт (1 гигабайт):
max_binlog_size= 500M
Сколько дней хранится:
expire_logs_days = 3
Наиболее часто использующиеся команды
Повторение действий после операции восстановления:
shell> mysqlbinlog log_file | mysql -h server_name
Удаление логов до определённого файла:
PURGE BINARY LOGS TO ‘mysql-bin.000’;
Удаление логов до определённой даты:
PURGE BINARY LOGS BEFORE ‘YYYY-MM-DD hh:mm:ss’;
Лог ошибок
Особенно полезен в случаях сбоев. Лог содержит информацию об остановках, запусках сервера, а также сообщения о критических ошибках. Может содержать сообщения с предупреждениями (warnings).
Основные настройки в my.cnf
Местоположение лога:
log_error = /var/log/mysql/mysql.err
Флаг, указывающий стоит ли записывать в лог в том числе предупреждения (записываются, если значение больше нуля):
log_warnings = 1
Наиболее часто использующиеся команды
Переход к новому файл лога:
shell> mysqladmin flush-logs
Копирование старой части лога (необходимо, так как в случае повторного выполнения fluch он будет удалён):
shell> mv host_name.err-old backup-directory
Лог медленных запросов
Если есть подозрение, что приложение работает медленно из-за неэффективных запросов к базе, то в первую очередь следует проверить лог медленных запросов. В случае оптимизации запросов этот лог поможет выяснить, что необходимо оптимизировать в первую очередь.
Основные настройки в my.cnf
Местоположение лога:
log_slow_queries = /var/log/mysql/mysql_slow.log
Со скольки секунд выполнения запрос считается медленным, минимальное значений — 1 секунда, по умолчанию 10 секунд:
long_query_time = 10
Если надо логировать запросы, которые не используют индексы, надо добавить строку:
log-queries-not-using-indexes
Если надо вести лог медленных команд, таких как OPTIMIZE TABLE , ANALYZE TABLE и ALTER TABLE :
log-slow-admin-statements
Лог запросов
Лог содержит информацию о подключениях и отключениях клиентов, а также все SQL запросы, которые были получены. Фактически, это временный лог. Обычно лог удаляется автоматически сразу после выполнения всех команд (т.е. как только он стал ненужным). Лог ведётся в соответствии с очередность поступления запросов. Этот лог содержит все запросы к базе данных (независимо от приложений и пользователей). Так что если есть желание (или необходимость) проанализировать, какие необходимы индексы, какие запросы могли бы оптимизированы, то этот лог как раз может помочь в таких целях. Лог полезен не только для случаев, когда необходимо знать, какие запросы выполняются с базой данных, но и в случаях, когда ясно, что возникла ошибка с базой данных, но неизвестно, какой запрос был отправлен к базе данных (например, в случае генерации динамического SQL-а). Рекомендуется защищать лог запросов паролем, так как он может данные также о паролях пользователей.
Основные настройки в my.cnf
Местоположение лога:
log = /var/log/mysql/mysql.log
Наиболее часто использующиеся команды
В отличии от других логов, перезагрузка сервера и команда fluch не инициирует создание нового лога. Но это можно сделать вручную:
shell> mv host_name.log host_name-old.log
shell> mysqladmin flush-logs
shell> mv host_name-old.log backup-directory
Лог репликаций
Здесь логируются изменения, выполненные по инициации сервера репликаций. Как и бинарный лог, состоит из файлов, каждый из которых пронумерован.
Основные настройки в my.cnf
Местоположение лога:
relay-log = /var/log/mysql/mysql-relay-bin.log
Максимальный размер:
max_relay_log_size = 500М
Наиболее часто использующиеся команды
Начать новый файл лога можно только при остановленном дополнительном (slave) сервере:
shell> cat new_relay_log_name.index >> old_relay_log_name.index
shell> mv old_relay_log_name.index new_relay_log_name.index
Команда fluch logs инициирует ротацию лога.
Записная книжка программиста-новичка, C#, SQL, PHP и все-все-все
Я ведь это уже делал, но хрен теперь найдешь тот кусок кода, гуглим снова… Где бы найти простое и понятное руководство для начинающего, а не тонкости для мега-гуру?
Главная→C#→ Чтение и запись двоичных файлов в базу данных MS SQL 2005 из C# используя OleDb
Рубрики
Свежие записи
- Вырезаем числовую часть из начала строки в transact-sql
- Пул соединений с базой данных в ADO.NET / OleDb — как избежать проблем с утечкой соединений в ASP.NET (перевод)
- ASP .Net MVC, JQuery и AJAX — отсылаем данные на сервер
- Разделитель тысяч и дробной части для decimal
- Создаем расширенный Control в WinForms наследуясь от существующего
- Вставка строк и изменение границ ячеек в Excel Interop из C#
- Как прочитать данные из удаленного DataRow в DataTable
- Проблемы с кодировкой при копировании русского текста из MS SQL Studio в Outlook/Word/Office
- Как проверить, существует ли таблица в MS SQL Server перед удалением/созданием
- Очень просто.
- Получаем выбранные строки DataGridView, в котором выбраны только ячейки
- Ошибка в коде привела к убыткам в 476 миллионов долларов и банкротству компании
- Отслеживаем изменения выбранного значения в колонке ComboBox DataGridView (DataGridViewComboBoxColumn)
- Excel 2010, Windows 7, два монитора и «ошибка при направлении команды приложению»
- Удаляем default-ограничение (constraint) в Transact Sql
Свежие комментарии
- Kirill к записи Самоучитель по C# для начинающих. 01. Основы языка, переменные, логика, циклы.
- как избавиться от чувства вины к записи Как добавить строку/текст в начало файла в C# и .Net
- DannyLef к записи Полезные расширения-плагины для WordPress
- как избавиться от чувства вины к записи Как добавить строку/текст в начало файла в C# и .Net
- gweg2ehgwEHERWQHQ к записи Простейшее диалоговое окно-вопрос (MessageBox) в WindowsForms
Архивы
Мета
Чтение и запись двоичных файлов в базу данных MS SQL 2005 из C# используя OleDb
Опубликовано 18.03.2011 автором Ведомир
Задача — хранить в базе данных MS SQL двоичные файлы. Это могут быть исполняемые файлы (для обновления приложения при запуске), документы Word или иные важные и нужные данные. Как и многие подобные задачи решается она просто, если знаешь за какие именно методы и свойства библиотечных классов надо дергать.
Двоичный данные в MS SQL 2005 хранятся в колонках типа VARBINARY(MAX). В более новых версиях сервера появились дополнительные средства, но на многих предприятиях до сих пор успешно работает 2005 версия, вполне удовлетворяя их потребности. В программе мы будем хранить их в массиве байтов byte[] — просто потому, что именно его поддерживаются соответствующие классы.
1. Прочитать файл с диска
2. Записать его в базу данных либо добавляя новую строку таблицы либо обновляя уже существующую
3. Прочитать с базы данных (под коду конкретного файла)
4. Записать на диск
Приступим!
0. Для хранения файлов в таблице базы данных надо эту таблицу создать. Какая неожиданность! Для тестовых целей можно создать такую таблицу
CREATE TABLE TEST_BINARY_FILES ( ID_FILE INT IDENTITY NOT NULL PRIMARY KEY, NAME_FILE VARCHAR(100) NOT NULL, DATE_LOAD DATETIME NOT NULL, BINARY_FILE VARBINARY(MAX) NOT NULL, SIZE_KBYTES FLOAT NOT NULL )
1. Читаем двоичный файл с диска.
Наша задача очень проста — получить массив всех байтов файла по его пути. заодно получим имя файла и расширение — запас карман не тянет. Специально для этого в библиотеке Net есть несколько простых и приятных методов класса Path — GetFileName, GetExtension; и класа File — ReadAllBytes. Скорее всего размер в килобайтах тоже можно получить стандартным методом — лень смотреть.
string name = Path.GetFileName(path); string type = Path.GetExtension(path); byte[] fileByteArray = File.ReadAllBytes(path); double kbSize = Math.Round(Convert.ToDouble(fileByteArray.Length) / 1024, 2);
Откуда мы возьмем путь? В приложении WinForms можно воспользоваться стандартным диалогом открытия файлов — это класс OpenFileDialog
OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.InitialDirectory = "d:\\"; // подразумевается выполнение кода внутри функции, например по клику на кнопке if (openFileDialog.ShowDialog() != DialogResult.OK) < return; >string filePath = openFileDialog.FileName;
2. Пишем массив байтов byte[] в колонку VARBINARY(MAX) базы данных MS SQL
Делается это абсолютно стандартными методами OleDbCommand с набором параметров и вставкой текущей даты функцией GETDATE() sql сервера
OleDbCommand dbCommand = dbConn.CreateCommand(); dbCommand.CommandText = "INSERT INTO TEST_BINARY_FILES (NAME_FILE, DATE_LOAD, BINARY_FILE, SIZE_KBYTES) VALUES (?, GETDATE(), ?, ?)"; dbCommand.Parameters.Add("name", OleDbType.VarChar, 100).Value = name; dbCommand.Parameters.Add("binaryData", OleDbType.VarBinary).Value = fileByteArray; dbCommand.Parameters.Add("kbSize", OleDbType.Double).Value = kbSize; dbCommand.ExecuteNonQuery();
или для обновления файла по коду
dbCommand.CommandText = "UPDATE TEST_BINARY_FILES SET NAME_FILE = ?, DATE_LOAD = GETDATE(), BINARY_FILE = ?, SIZE_KBYTES = ? FROM TEST_BINARY_FILES WHERE ID_FILE = ?"; dbCommand.Parameters.Add("name", OleDbType.VarChar, 100).Value = name; dbCommand.Parameters.Add("binaryData", OleDbType.VarBinary).Value = fileByteArray; dbCommand.Parameters.Add("kbSize", OleDbType.Double).Value = kbSize; dbCommand.Parameters.Add("idFile", OleDbType.Integer).Value = dbFileKod; dbCommand.ExecuteNonQuery();
3.Читаем содержимое поля VARBINARY(MAX) в массив байтов byte[]
OleDbCommand dbCommand = dbConn.CreateCommand(); dbCommand.CommandText = "SELECT BINARY_FILE FROM TEST_BINARY_FILES WHERE ID_FILE = ?"; dbCommand.Parameters.Add("idFile", OleDbType.Integer).Value = dbFileID; byte[] fileByteArray = (byte[]) dbCommand.ExecuteScalar();
4. Записать на диск. Для решения этой задачи используем классы BinaryWriter и FileStream
FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); BinaryWriter binWriter = new BinaryWriter(fileStream); binWriter.Write(fileByteArray); binWriter.Close();
Для получения пути к файлу в приложении WinForms можно точно так же использовать стандартный диалог сохранения файла — класс SaveFileDialog
SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.InitialDirectory = "d:\\"; if (saveFileDialog.ShowDialog() != DialogResult.OK) < return; >string filePath = saveFileDialog.FileName;
И в завершение напишем простенький класс для работы с двоичными файлами
class BinaryFile < string name; byte[] byteArray; string extension; double kbSize; DateTime lastChanged; public string Name < get < return this.name; >> public string Extension < get < return this.extension; >> public Byte[] ByteArray < get < return this.byteArray; >> public double KbSize < get < return this.kbSize; >> public DateTime LastChanged < get < return this.lastChanged; >> public BinaryFile(string path) < this.loadFromDisk(path); >public BinaryFile(byte[] inputByteArray, string fileName, DateTime lastChanged) < this.loadFromByteArray(inputByteArray, fileName, lastChanged); >public void loadFromDisk(string path) < name = Path.GetFileName(path); extension = Path.GetExtension(path); byteArray = File.ReadAllBytes(path); kbSize = Math.Round(Convert.ToDouble(byteArray.Length) / 1024, 2); lastChanged = File.GetLastWriteTime(path); >public void saveToDisk(string path) < FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite); BinaryWriter binWriter = new BinaryWriter(fileStream); binWriter.Write(this.byteArray); binWriter.Close(); >public void loadFromByteArray(byte[] inputByteArray, string fileName, DateTime inputLastChanged) < name = fileName; extension = Path.GetExtension(fileName); byteArray = inputByteArray; kbSize = Math.Round(Convert.ToDouble(byteArray.Length) / 1024, 2); lastChanged = inputLastChanged; >// завершение class BinaryFile >
Более подробно работа с MS SQL Server рассмотрена в статье Чтение и запись данных на MS SQL Server с помощью OLE DB и ADO.NET.
Комментарии
Чтение и запись двоичных файлов в базу данных MS SQL 2005 из C# используя OleDb — Комментарии (4)
Очень надо Ваша помошь, гоняюсь за этим кодом уже неделю но не могу найти в реализации Windows Form, как этот код можно вставить в нее, я тока начинающий програмист, прошу напишите на мой маил
Ведомир говорит 16.06.2011 в 5:41 :
Слава: не могу найти в реализации Windows Form, как этот код можно вставить в нее, я тока начинающий програмист,
В планах самоучитель по Windows Forms, но к сожалению времени и сил не хватает на все задумки. Данная статья (как и руководство по работе с базой данных MS SQL) предназначена для разработчика, которые уже умеет писать несложные приложения на WinForms — рисовать форму, обрабатывать события на ней.
That’s a cunning answer to a chnlnelgiag question
Привет! Если содержимое двоичного файла при каждом запуске программы переписывается от начала до конца, то он всегда будет содержать только необходимые данные. Иначе обстоит дело, если двоичный файл при очередном запуске редактируется. Тогда при