Показаны сообщения с ярлыком Tips. Показать все сообщения
Показаны сообщения с ярлыком Tips. Показать все сообщения

27.09.2021

Azure: построение кросс-запросов для различных БД в MS Azure SQL Server

 MS Azure SQL Server с точки зрения взаимодействия с ним крайне похож на классический MS SQL Server и во многих аспектах повторяет функциональность. Однако быстрое и удобное создание linked server пока не доступно в Azure версии. В качестве решение можно воспользоваться способом с подключением внешнего источника данных:

-- Производим очистку данных
DROP EXTERNAL TABLE tblSource
DROP EXTERNAL DATA SOURCE RemoteSource
DROP DATABASE SCOPED CREDENTIAL sourceCredential
DROP MASTER KEY

-- Настраиваем соединение
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'your_password';

CREATE DATABASE SCOPED CREDENTIAL sourceCredential
WITH IDENTITY = 'your_login',
SECRET = 'your_password';

CREATE EXTERNAL DATA SOURCE RemoteSource
WITH
(
    TYPE=RDBMS,
    LOCATION='your_server.database.windows.net',
    DATABASE_NAME='your_db_name',
    CREDENTIAL= sourceCredential
);

CREATE EXTERNAL TABLE dbo.tblSource(
    [Id] [int] NOT NULL,
    [Name] [nvarchar](2000) NOT NULL
)
WITH
(
    DATA_SOURCE = RemoteSource
);

-- Производим выборку
SELECT * 
FROM dbo.tblSource

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

20.04.2021

SQL: Функция для получения по подстрок из строки с разделителями

Возникла задача по разбиения строкового столбца, в котором есть разделители, например, точка с запятой на отдельные столбцы. Для этого из оригинальной строки нужно получать подстроки с учетом порядкового номера/индекса. Сделать это можно, написав sql-функцию следующего вида:

CREATE FUNCTION [dbo].[f_GetValueFromSeparatedStringByIndex]
(
    @InputString nvarchar(MAX),
    @Index int,
    @Separator nvarchar(1) = ';'
)
RETURNS nvarchar(255)
AS
BEGIN
    DECLARE @Result nvarchar(255) = NULL

    SELECT @Result = TRIM(Value)
    FROM (
        SELECT TRIM(value) as Value, ROW_NUMBER() OVER(ORDER BY (SELECT 1)) as OrderNumber
        FROM string_split(@InputString, @Separator)
    ) as t
    WHERE OrderNumber = @Index

    RETURN  @Result
END

25.03.2021

Azure: Проблема масштабирования SQL Database при включенном резервном копировании

Недавно наткнулся на интересный момент. В рамках MS Azure при попытке перемасштабировать базу с DTU-варианта на виртуальные ядра с включенным автоотключением падает неизвестная ошибка без какой-либо детализации. Экспериментальным образом удалось выяснить, что проблема заключалась в настроенном у БД резервном копировании. При его оключении масштабирование проходит успешно. 

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

24.02.2020

SQL: Получение списка запросов, ожидающих доступ к вычислительным ресурсам

Иногда запрос может выполняться очень долго, т.к. не может получить доступ к вычислительным ресурсам. Такое часто встречается при большом количестве одновременных обращений из разных источников. Получить список всех запросов, ожидающих доступ к ресурсам, в MS SQL Server можно следующим образом:
SELECT  wt.session_id, 
        ot.task_state, 
        wt.wait_type, 
        wt.wait_duration_ms, 
        wt.blocking_session_id, 
        wt.resource_description, 
        es.[host_name], 
        es.[program_name] 
FROM  sys.dm_os_waiting_tasks  wt  
INNER  JOIN sys.dm_os_tasks ot ON ot.task_address = wt.waiting_task_address 
INNER JOIN sys.dm_exec_sessions es ON es.session_id = wt.session_id 
WHERE es.is_user_process =  1 

SQL: Остановка длительных запросов

Если база данных является высоконагруженной и работает в конкурентном окружении, то достаточно часто возникает задача остановки длительных запросов, если они мешают выполнению других запросов. Приведу здесь наиболее популярные конструкции для поиска и удаления запросов.
  1. Получение списка всех активных сессий вместе с учетными записями, под которыми они запущены:
    SELECT conn.session_id, host_name, program_name,
        nt_domain, login_name, connect_time, last_request_end_time 
    FROM sys.dm_exec_sessions AS sess
    JOIN sys.dm_exec_connections AS conn
       ON sess.session_id = conn.session_id
    
  2. Получение списка всех запущенных запросов с индентификатором открытой сессии и временем запуска:
    SELECT  sqltext.TEXT,
            req.session_id,
            req.status,
            eq.start_time,
            req.command,
            req.cpu_time,
            req.total_elapsed_time
    FROM sys.dm_exec_requests req
    CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext
    
  3. Получить информацию о том, какие активные соединения в настоящее время установлены с SQL Server, можно так:
    sp_who2 'active'
    
  4. Завершение пользовательского процесса по идентификатором сеанса:
    KILL 'your_session_id'
    

04.09.2019

Python: Online IDE

Бывают ситуации, когда нет возможности установить на компьютер необходимую среду разработки (например, из-за ограничений политик безопасности компании) или нужно проверить идею. В этом случае могут помочь облачные IDE. Здесь приведен список наиболее популярных сервисов, поддерживающих Python, хотя некоторые из них могут использовать и другие языки:
  1. repl.it
  2. sourcelair.com - также поддерживает js.
  3. jupyter.org/try - один из самых популярных редакторов. Позволяет использовать не только Python, но и R, C++, Ruby и Scheme.

C#: Поиск элементов в списке строк без учета регистра

Небольшое, но полезное расширение для List<string>, позволяющее осуществлять поиск элементов в списке строк без учета регистра:
public static bool Contains(this string target, string value, StringComparison comparison)
{
    return target.IndexOf(value, comparison) >= 0;
}

16.02.2019

Azure: ошибка 425 при подключении к FTP

На Azure была создана свежая виртуальная машина, на которой был развернут FTP-сервер Filezilla. В брендмауэре как винды, так и виртуальной машины был открыт входящий порт 21 (по умолчанию для FTP). Соединение с сервером выполнялось, но после хендшейка выдавалась ошибка 425, после чего соединение падало.
Ларчик открывался просто: FTP- сервер сообщал клиенту, что нужно использовать порты для пассивного режима, по умолчанию для Filezilla  это 6091-6092. Поэтому, чтобы все заработало нужно открыть их во всех фаерволах.

Azure: solving KMS license activation problem on virtual machines

For about a month I had a lot of work with Microsoft Azure. This cloud is best I worked with, however even it has some bugs. I fpind that sometimes newly created Windows Server or Window 10 virtual machines can not be automatically activated. After several iterations of commucation with MS tech support we found the solution of the problem. Follow the steps:
  1. First of all you should check the availability of Azure KMS server with the following cmd command:
    nslookup -type=srv _vlmcs._tcp
    
  2. Set a proper key for your Windows version:
    slmgr.vbs -ipk 
    
    The list of keys can be found here. For example for Win2k12 it will be
    slmgr.vbs -ipk W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9
    
  3. Set a correct KMS server:
    slmgr /skms kms.core.windows.net:1688
    or
    slmgr.vbs -skms http://kms.core.windows.net:1688
    
  4. And finally perform activation:
    slmgr.vbs /ato
Some steps can be overkill with your particular case, but sometimes you should repeat a command to get it working. Hope it helps.

Confluence: unknown server error при создании пространства

На днях разворачивал Confluence 6.14, после добавления пары новых плагинов и перезагрузки перестали создаваться новые пространства. При этом выдавалось сообщение "An unknown server error has occurred". Проблема, как и можно было предположить, крылась в ошибках шаблонов пространств. Помогло удаление соответствующих таблиц:

DROP TABLE AO_54C900_SPACE_BLUEPRINT_AO
DROP TABLE AO_54C900_C_TEMPLATE_REF
DROP TABLE AO_54C900_CONTENT_BLUEPRINT_AO

После удаления и попытки создания нового пространства таблицы создаются заново, но все равно рекомендую всегда делать бэкапы. Возможно данный трюк поможет и в других версиях Confluence.

30.11.2018

DTO vs POCO vs Value Object

Иногда возникает путаница, когда разработчики применяют терминологию DTO vs POCO vs Value Object. Я нашел хорошую статью, из которой привожу краткую выжимку.

DTO (Data Transfer Object) — это класс, содержащий данные без какой-либо логики для работы с ними. DTO обычно используются для передачи данных между различными приложениями, либо между слоями внутри одного приложения.

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

POCO (Plain Old CLR Object) означает использование настолько простых классов насколько возможно для моделирования предметной области. POCO классы могут содержать логику.

При этом можно привести следующую зависимость между терминами.
DTO != Value Object
DTO ⊂ POCO
Value Object ⊂ POCO

09.11.2018

C#: Реализация Many-To-Many в Entity Framework 6

Пускай у нас будут две модели Articles (статьи) и Authors (авторы статей). У статей может быть несколько авторов, а авторы могут участвовать в написании нескольких статей. Ниже представлен шаблон для реализации конструкции связей Many-To-Many в Entity Framework 6, например, его можно использовать в рамках концепции Code-First для автоматического создания таблиц связей.

public class Article
{
    public int Id { get; set; }

    public string Title { get; set; }

    public string Surname { get; set; }

    public virtual ICollection Authors { get; set; }

    public Article()
    {
        Authors = new List();
    }
}

public class Author
{
    public int Id { get; set; }

    public string Fio { get; set; }

    public virtual ICollection  Articles { get; set; }
public Author() { Articles = new List();
} } public class Arctiles2AuthorsContext : DbContext { public DbSet Authors { get; set; }
public DbSet Articles { get; set; } public Arctiles2AuthorsContext() : base("DefaultConnection") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity().HasMany(c => c.Articles) .WithMany(s => s.Authors) .Map(t => t.MapLeftKey("ArticleId") .MapRightKey("AuthorId") .ToTable("Arctiles2Authors")); } }

02.11.2018

TDD: тестирование приватных методов

В рамках обсуждения TDD (test driven development) периодически возникает вопрос: как тестировать приватные методы. Если не отвлекаться на вопрос о том, нужно ли тестировать их вообще, т.к. тестировать следует только публичные методы (это вопрос религиозных предпочтений), то вот несколько способов для написания unit-тестов приватных методов в .net:
  1. Делать метод не private, а public, оставляя комментарий о том, чтобы вернуть инкапсуляцию при создании release сборки. Это самый спорный метод, но тоже может встречаться. Как вариант, можно использовать директиву DEBUG:
    #if DEBUG
            public FileManager(IDataAccessObject dataAccessObject)
            {
                this.dataAccessObject = dataAccessObject;
            }     
    #else
            public FileManager()
            {
                this.dataAccessObject = new FileDataObject();
            }
    #endif
  2. Делать тестируемый метод не private, а protected и создавать наследуемый класс, в котором уже будет тестироваться данный метод.
  3. Вместо private делать методы internal, при этом при объявлении класса добавлять атрибут:
    [assembly: InternalsVisibleTo("You_lib")]
    
  4. При использовании MSTest можно задействовать класс PrivateObject, который позволяет вызывать private методы по имени.
  5. Использовать рефлексию.

30.10.2018

Паттерны проектирования

Недавно вдохновившись циклом статей "Основы паттернов проектирования", сделал проект на Github, содержащий в себе шпаргалку для наиболее часто использующихся паттернов на языке C# (доступно по ссылке). Теперь, если понадобится использовать какой-нибудь паттерн, можно будет быстро прочитать его описание, критерии и примеры оптимального использования и взять заготовку. Надеюсь, что будет полезно не только мне, но и другим.

PS. UML-схемы паттернов в качестве небольшой бонус с telegram-канала "Библиотека программиста"





12.09.2018

DataScience: отличные курсы и подборка бесплатных книг

Немного устаревшая информация,  но может быть полезно всем любителям DataScience. На хабре хорошие люди выложили статью, в которой они делятся ссылками на бесплатные книги по DataScience. Ну, а со своей стороны хочу порекомендовать пару курсов по данной теме на Coursera:
1. Machine-learning (Stanford University)
2. Машинное обучение и анализ данных (Яндекс, МФТИ)
Последний в списке курс проходил лично, считаю его для себя очень интересным и полезным, хотя и требующим неплохой базовой математической подготовки.

30.08.2018

WPF: Binding

Последнее время приходится много писать на WPF. Открыл для себя неплохую шпаргалку по синтаксису биндинга. Может быть полезна для тех, кто только начинает работу с WPF. Файл  доступен по ссылке.

09.08.2018

Таблица соответствия типов данных для SQL Server и CLR

Ниже приведена таблица соответствия типов данных для SQL Server и CLR (оригинал доступен по ссылке)

SQL Server data type          CLR data type (SQL Server)    CLR data type (.NET Framework)  
varbinary                     SqlBytes, SqlBinary           Byte[]  
binary                        SqlBytes, SqlBinary           Byte[]  
varbinary(1), binary(1)       SqlBytes, SqlBinary           byte, Byte[] 
image                         None                          None

varchar                       None                          None
char                          None                          None
nvarchar(1), nchar(1)         SqlChars, SqlString           Char, String, Char[]     
nvarchar                      SqlChars, SqlString           String, Char[] 
nchar                         SqlChars, SqlString           String, Char[] 
text                          None                          None
ntext                         None                          None

uniqueidentifier              SqlGuid                       Guid 
rowversion                    None                          Byte[]  
bit                           SqlBoolean                    Boolean 
tinyint                       SqlByte                       Byte 
smallint                      SqlInt16                      Int16  
int                           SqlInt32                      Int32  
bigint                        SqlInt64                      Int64 

smallmoney                    SqlMoney                      Decimal  
money                         SqlMoney                      Decimal  
numeric                       SqlDecimal                    Decimal  
decimal                       SqlDecimal                    Decimal  
real                          SqlSingle                     Single  
float                         SqlDouble                     Double  

smalldatetime                 SqlDateTime                   DateTime  
datetime                      SqlDateTime                   DateTime 

sql_variant                   None                          Object  
User-defined type(UDT)        None                          user-defined type     
table                         None                          None 
cursor                        None                          None