Quantcast
Channel: SQL.ru: Microsoft SQL Server
Viewing all 7251 articles
Browse latest View live

Валидация метаданных excel файла с помощью T-SQL

$
0
0
Добрый вечер,

Есть целевая задача, которая требует загрузить данные из Excel файла в существующую таблицу на SQL-сервере.

Перед реальной загрузкой (по сути это будет merge) необходимо будет выполнить валидацию в 2 этапа:
1. Валидация метаданных (надеюсь правильно выражаю суть этим словом) excel-файла с помощью T-SQL;
2. Валидация данных excel-файла с помощью T-SQL перед выполнением Merge с существующей таблицей.

Оба случая требуют выполнения логирования, т.е. записать, что было не так с файлом и данными в нем.

Второй этап я пока что опущу, т.к. особой сложности в нем не вижу, но есть некие вопросы, которые скорее всего озвучу в другой теме позже.


Итак, первый этап - валидация метаданных.
Мои вводные:
1. Структура Excel-файла предопредела заранее, но, как это часто бывает, что-то может пойти не так и могут потеряться столбцы, их названия, их порядок в файле и т.д. Вот это я должен проверить, что загружаемый файл соответствует требованиям.
Предположим файл состоит из 7 столбцов со следующими названиями и типами:
- ID (int)
- Name (nvarchar(256))
- Address (nvarachar(512))
- Phone (nvarchar(24))
- Col1 (bigint)
- Col2 (numeric(15, 4))
- Col3 (bit)

Если какой-то столбец пропал в файле, то я должен это записать в таблицу логов
Если название у какого-то из столбцов не соответствует требованиям - аналогично записываю.
Если тип (можно попытаться по данным определять) не соответствует требованиям - также пишу в лог.
Если порядок столбцов нарушен - аналогично пишу в лог.

Как только Excel-файл будет соответствовать на все 100% требованиям я смогу перейти ко второму этапу.

Данные всегда будут находится на первой странице файла.

Грузить данные я могу исключительно 2 способами:
1. С помощью CLR-функции
2. С помощью Linked Server через openquery

SSIS отпадает сразу, поэтому не стоит предлагать его.


Пытался по разному спрашивать гугл, но ничего не помогло...
Буду благодарен за любые подсказки.

Из того, что мне удалось сейчас придумать - это непосредственная загрузка имеющихся данных из Excel-файла во временную таблицу (через CLR или Linked Server), где далее я по имени этой временной таблицы обращаюсь в базе tempdb к обьекту sys.columns и получаю список названий столбцов, которые были в файле с их порядком. После этого делаю с помощью конструктура табличных выражений свою эталонную таблицу с порядком столбцов и их названиями и к этому результату применяю EXCEPT отсортированного результата из sys.columns. То есть сравниваю порядки с их названиями и если где-то не совпало, то я считаю, что структура не корректна.

Мне кажется, что должно существовать более красивое решение этой задачи.
Может кто знает его или подскажет где поискать?

Если каких-то данных не хватает, то напишите.

Спасибо!

Сравнение таблицы из БД и бекапа этой БД

$
0
0
Добрый день.

Задача такая: нужно сравнить данные таблицы из БД и бекапа этой БД с помощью sql скрипта, т.е. программно. Есть полный путь к бекапу(файл bak), нужно поднять этот бекап, но не накатывать его, их этого бекапа взять данные таблицы и сравнить с таблицей из текущей развернутой версии БД.
Подскажите , пожалуйста, в какую сторону копать? В первую очередь интересует как данные таблицы из бекапа перевести в вид которым можно потом манипулировать через t-sql.

ps: параллельно буду смотреть форум, но в основном пишут про какие то ошибки , проблемы, а тут наверное вопрос на знание мат части( t-sql, и механизм работы с бекапом не накатывая его на сервер)

Import DB file (MSSQL)

$
0
0
Eсть файл DB. Kаким способом можно взять данные из файла?
Модератор: Дружище, хорош плодить темы, лады?

апостроф при экспорте в csv , экранирование в ""

$
0
0
При экспотре в csv надо заключать слова содержащие апостров в двойные кавычки "", какие есть варианты, подскажите пожайлуста?

Пример:
Дано в таблице:
1)4820 NUTTER'S CROSS RD.
2)11110 CHAMBERS CT. 'D'

Надо получить в файле
1)4820 "NUTTER'S" CROSS RD.
2)11110 CHAMBERS CT. "'D'"

Прибавка нулей к строке чисел

$
0
0
Добрый день. Возможно и тривиальная задача, но прошу помощи.

Есть таблица значений, она большая, Num:
Number
613
2356
42698

Необходимо прибавить столько '0' к столбцу Number, чтобы значения столбца были ровно 6. То есть должно получится так:

NewNumber
000613
002356
042698

Можно конечно с условием поработать, но думаю есть решение с вычислением разницы, но незнаю каким образом.

FILESTREAM

$
0
0
Скажите пожалуйста,

создал БД FILESTREAM с таблицей FileTable
можно ли клиентским приложением копировать файл в БД простым копированием (
System.IO.File.Copy
) в каталог ...\mssqlserver\FileTable\Files ?

Заранее благодарен.

как развернуть строку в столбец при условиии

$
0
0
есть данные в табл на рис.

при условии что glhip_app_id и elhyp_app_id is not null выводить необходимо

CFO_ID hyp_app
18332 40
18332 30

иначе только данные где нет null значения

select cfo_id, glhip_app_id,elhyp_app_id from table 1 

Помогите разобраться с xml explicit

$
0
0
Хочу сформировать такой XML:
<msg id="1">
  <row lang="ru" msg="Пользователь=[1] не играет в игре id=[2]">
    <param>Вася</param>
  </row>
  <row lang="en" msg="User name=[1] does not play in the game id=[2]">
    <param>Vasa</param>
    <param>7777</param>
  </row>
</msg>

<msg id="2">
  <row lang="ru" msg="Ошибка" />
  <row lang="en" msg="Error" />
</msg>

из таких данных:
id	lang	msg	param
1 en User name=[1] does not play in the game id=[2] Vasa
1 en User name=[1] does not play in the game id=[2] 7777
1 ru Пользователь=[1] не играет в игре id=[2] Вася
2 ru Ошибка NULL
2 en Error NULL
Т.е. первый тег msg с аттрибутом id, далее вложенный row, в row аттрибут lang, ну и параметры уже как элементы вложенные в 3й уровень... Читаю БОЛ с эксплисит... нифига не получается. Подскажите или запрос как корректно нарисовать или какую то документацию понятную на примерах?
+ запрос такой...
if object_id('tempdb..#t') is not null drop table #t
select
	 m.*
	,p.param
into #t
from
(
	values
	 (1,'en','User name=[1] does not play in the game id=[2]')
	,(1,'ru','Пользователь=[1] не играет в игре id=[2]')
	,(2,'ru','Ошибка')
	,(2,'en','Error')
) m(id,lang,msg)
left join
(
	values
	 (1,'en','Vasa')
	,(1,'en','7777')
	,(1,'ru','Вася')
) p(id, lang, param)
	on m.id = p.id
	and m.lang = p.lang


select distinct
	 1 as Tag
	,null as Parent
	,id as [msg!1!id]
	,null as [msg!2!row!element]
	,lang as [msg!2!lang]
	,msg as [msg!2!msg]
	,param as [msg!3!param!element]
from #t
union all
select distinct
	 2 as Tag
	,1 as Parent
	,null
	,id
	,lang
	,msg
	,param
from #t
union all
select distinct
	 3 as Tag
	,2 as Parent
	,id
	,null
	,lang
	,msg
	,param
from #t
for xml explicit

declare @x xml = '
<msg id="1">
	<row lang="ru" msg="Пользователь=[1] не играет в игре id=[2]">
		<param>Вася</param>
	</row>
	<row lang="en" msg="User name=[1] does not play in the game id=[2]">
		<param>Vasa</param>
		<param>7777</param>
	</row>
</msg>
<msg id="2">
	<row lang="ru" msg="Ошибка" />
	<row lang="en" msg="Error" />
</msg>'
select @x

подсчет одновременых подключений к БД

$
0
0
я сделал таким способом:
SELECT CONVERT(VARCHAR, GETDATE(), 120) Time,
       d.name DbName,
       s.program_name ProgramName,
       COUNT(DISTINCT s.spid) CountSpid
FROM sys.sysprocesses s
JOIN sys.databases d ON d.database_id = s.dbid
  AND s.dbid > 4
GROUP BY d.name,
         s.program_name

но может есть более корректные способы?

Авторизация в SQL 2012 EXPRESS

$
0
0
Всем привет.
Есть w2008 и Ms SQL 2012 EXPRESS. Есть сторонее приложение, которое к нему коннектится. Есть у этого приложения .ini файл в котором указывается к какой базе и каким способом нужно подключаться. Вот как он выглядит со способом авторизации windows пользователя:

<?xml version="1.0" encoding="windows-1251"?>
<app_config>
<storage>
<type>sql</type>
<server>SRV01\SQLEXPRESS</server>
<database>mybase</database>
<conn_options>Provider=SQLOLEDB;Integrated Security=SSPI</conn_options>
</storage>

<logs_dir></logs_dir>
</app_config>


В этом случае приложение не может подключиться к базе данных и записывает в своих логах такое событие:

---
Не удается открыть базу данных "mybase", запрашиваемую именем входа. Не удалось выполнить вход.
18:47:06 [11408] Terminating...
18:47:06 [11408] STOPPED
xHTTP server build 07.10.2015
Copyright (c) 2003-2011 Datex Software
18:47:35 [11148] CHARSET: windows-1251
18:47:35 [11148] Initializing...
18:47:35 [11148] Serial number checked
18:47:35 [11148] Ошибка подключения к базе SQL
---


Но если в .ini файле прописать способ авторизации через пользователя MSSQL в таком виде:

<?xml version="1.0" encoding="windows-1251"?>
<app_config>
<storage>
<type>sql</type>
<server>srv01\SQLEXPRESS</server>
<database>mybase</database>
<conn_options>Provider=SQLOLEDB;User ID=vasy;Password=1234567890;Trusted_Connection=False</conn_options>
</storage>

<logs_dir></logs_dir>
</app_config>


то в этом случае программа успешно подключается к базе.
При этом в SQL Server managment studio я могу успешно подключаться любым из способов авторизации. Помогите разобраться в чем может быть проблема?

change tracking SQL

$
0
0
настраиваю Change Tracking чтобы отслеживать изменения в таблице. Настроил изменения на последние 24 часа. С Insert все понятно, видно какие новые строки добавились.
Как отследить update?
 SELECT * FROM CHANGETABLE(CHANGES dbo.table , null) AS a 


Показывает что произошел Update в строке i, как расшифровать SYS_CHANGE_COLUMNS ? Хочу видеть что на что поменялось, а не только строку. Это можно увидеть ?

Microsoft SQL Server 2017 (RTM-CU8) (KB4338363) - 14.0.3029.16 (X64) Jun 13 2018 13:35:56 Copyright (C) 2017 Microsoft Corporation Developer Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: ) (Hypervisor)

Получить остаток на документ в обратном порядке по дате документа?

$
0
0
Здравствуйте. есть 2 таблицы. 1 - остатки, 2 - движения (приход, расход). В первой таблице хранятся остатки по Контрагентам и Договорам, во второй таблице хранятся фактические движения, т.е. все приходы и расходы по каждому документу (таблица документов). Вопрос такой, Делается запрос по таблице остатков, получаются остатки и теперь надо найти первейший документ, на котором возникает остаток больше 0. Вот запрос получения остатков:
SELECT
Контрагент,
Договор,
СуммаДолга
FROM ТаблицаОстатков

А вот запрос по получению движений:
SELECT
Контрагент,
Договор,
Документ,
ДатаДокумента,
СуммаОборот
FROM ТаблицаДвижений

Теперь надо как-то эти 2 таблицы объединить, чтобы получить остаток из таблицы остатков и отнять от нее все Обороты с таблицы оборотов до даты документу, включая текущий документ. Помогите пожалуйста написать наиболее оптимальный запрос для получения таких остатков. Спасибо.

Восстановить базу SQL

$
0
0
Добрый день!
Мне нужно срочно восстановить базу SQL. Не поднимается,диск посыпался,повреждено 60% но на демо версии SQL Repair смог базу прочитать,правда она не сохраняет. Вес 1гиг.. Возьмитесь пжл кто-нить!

Проверка запущена ли процедура через sys.sysprocesses

$
0
0
Добрый день.
Для моей задачи необходимо проверять запущена ли в данный момент процедура.

Пытаюсь сделать это так:

select 1
from sys.sysprocesses as qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
where object_name(st.objectid) = 'Моя_процедура'

Когда тестировал данный способ все работало прекрасно. Те запускал тестовую процедуру и скрипт выдавал значение = 1.
Но когда я запускаю боевую процедуру то вышеуказанный скрипт ее в упор не видит. В чем может быть проблема? Это же не может быть связано со сложностью самой процедуры?

Очередность блокировок в JOIN

$
0
0
Есть таблицы А и В.

В одной сессии выполняем

update A set ... where...


У таблицы А есть триггер, где модифицируется таблица В:

update t
  from inserted i, deleted d, B t...


таким образом, сперва накладывается X-блокировка на таблицу А, а затем IX на таблицу В. Пока понятно.

В другой сессии выполяется запрос

select..
  from B join A


так вот, оказывается, что этот запрос накладывает свои S-блокировки сперва на В, а затем пытается на А.
И получается классический deadlock - доступ к двум ресурсам в разном порядке.

Самое простое, что советуют в этом случае - сделать порядок доступа одинаковым. Но как это сделать для SELECT с JOIN ?

Есть ли какие-то хинты, которые бы задавали очередность наложения блокировок?

MS SQL 2014. Обе транзакции READ COMMITTED.

PS. Про READ_COMMITTED_SNAPSHOT знаю, но он выключен, включать его не в моей компетенции. Хотелось бы попробовать обойтись управлением блокировками.

Как получить текст запроса для процесса?

$
0
0
Всем привет!
Подскажите пожалуйста как получить текст запроса для для процесса?
sys.dm_exec_sql_text показывает текст запроса только в том случае если есть кешированный план, а если плана нет то и текст посмотреть нельзя.

Как сджойтить 2 таблицы не по ключу.

$
0
0
Подскажите пожалуйста.
вот есть две таблицы

SELECT TOP (1000) [CustomerName]
      ,[PayerName]
      ,[ItemRelation]
      ,[DocumentNum]
      ,[DocumentYear]
      ,[CustomerType]
      ,[k]
      ,[m0]
      ,[Action_Effect]
      ,[sum]
      ,[salesbefore]
  FROM [Action].[dbo].[deduped2]


и
SELECT TOP (1000) [CustomerName]
      ,[PayerName]
      ,[ItemRelation]
      ,[DocumentNum]
      ,[DocumentYear]
      ,[CustomerType]
      ,[k]
      ,[m0]
      ,[Action_Effect]
      ,[sum]
      ,[salesbefore]
  FROM [Action].[dbo].[FSEA]


несмотря на то что их колонки одинаково называются, общего ключа нет.
там просто соответствующие данные, которые надо соединить по колонкам

т.е.
в одной таблице
а
б
в
в другой таблицеъ
г
д
е

а в результате должно быть

а
б
в
г
д
е

Как так приджойнить 2 таблички?

select из xml

$
0
0
Помогите новичку.

Есть таблица в базе, в ней в одном из полей - xml структура. Тип поля xml.

CREATE TABLE [dbo].[Task](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[StatusId] [int] NOT NULL,
	[ServiceId] [int] NOT NULL,
	[CreatorId] [int] NOT NULL,
	[Data] [xml] NULL,
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO


data это что-то типа:

<data>
<field id="1171">2018-07-10 00:00</field>
<field id="1172">84</field>
<field id="1173">95</field>
<field id="1174">Документация</field>
<field id="1175">Профилактика</field>
<field id="1190">Иванов Иван Иванович</field>
</data>

В нашей выборке структура везде одинаковая.

SELECT id, statusid, creatorid, data  FROM [dbo].[Task] where serviceid=74

id	statusid	creatorid	data
4983	28	35822	<data><field id="1171">2018-07-10 00:00</field><field id="1172">84</field><field id="1173">95</field><field id="1174">Документация</field><field id="1175">Профилактика</field><field id="1190">Иванов Иван Иванович</field></data>
4978	28	35904	<data><field id="1171">2018-07-11 00:00</field><field id="1172">78</field><field id="1173">714</field><field id="1174">испытание</field><field id="1175">город</field><field id="1190" /></data>
4975	28	35846	<data><field id="1171">2018-07-10 00:00</field><field id="1172">82</field><field id="1173">96</field><field id="1174">Прием</field><field id="1175">Офис</field><field id="1190" /></data>


Требуется получить развернутую табличку, вместе с данными лежащими в xml'е, в виде отдельных столбцов.

Понимаю что не сложно, но в SQL ничего сложнее select from where Не использовал...
А в идеале еще бы выборку ограничить по одному из field id.
Там еще join ы из других таблиц добавятся, дабы Id шники заменить на вменяемые значения но это я уж сам, там хоть понятно в целом.


Всегда Ваш, konst

Нужна помощь разбитие таблицы на две с последующим присвоением id

$
0
0
MS SQL 2012
Необходимо разбить существующую таблицу с данными на две и связать по ключевым полям.
Делал это несколькими способами:
1. Создавал таблицу в существующей БД вручную соответственно типы полей совпадают
и затем
INSERT INTO Table2 (a1,a2,a3,a4)
SELECT DISTINCT a1,a2,a3,a4
FROM Table1
WHERE Table1.a1 IS NOT NULL

2.
SELECT DISTINCT a1,a2,a3,a4
INTO Table2
from Table1

затем

UPDATE Table1
SET Table1.ID_a=Table2.ID_a
FROM Book JOIN Table2
ON (Table1.[a1] = Table2.[a1]) AND (Table1.[a2] = Table2.[a2])
AND (Table1.[a3] = Table2.[a3]) AND (Table1.[a4] = Table2.[a4])


Проблема в том, что если после ON только два сравнения (Table1.[a1] = Table2.[a1]) AND (Table1.[a2] = Table2.[a2]), всё ок всем записям соотвествуют ID, а если четыре то не всем.. в чём может быть косяк? Значения с пробелами, но на сколько я знаю пробелы при сравнении в начале и в конце не учитываются, это даже если они обрезаются при переносе... Пробовал без DISTINCT тоже самое

Автоматически выполнить скрипт перед выполнением бэкапа

$
0
0
Привет всем.

В БД есть табличка с различными временными расчётными данными/логами, актуальность которых варьируется от 10 минут до 5-8 часов. Потеря этих данных не критична от слова совсем, т.е. в бэкапе они никому не нужны.
Есть ли возможность в MS SQL Server задать для БД скрипт, который автоматически выполнялся бы перед бэкапом. Т.е. я в Management Studio жамкаю Backup, указываю имя файла, жму "Ок", автоматически запускается скрипт чистящий эти данные и следом делается сам бэкап.

Гуглил, читал FAQ, искал здесь по форуму. Не помогло.

Спасибо.

--
Если я рассуждаю логично, это значит только то, что я не сумасшедший, но вовсе не доказывает, что я прав (с)И.П. Павлов
Viewing all 7251 articles
Browse latest View live