반응형

인터페이스 다중 상속 시 메소드명이 동일한 경우에는 해당 메소드는 명시적 구현 즉 '인터페이스명.메소드명' 형식으로 해야 합니다.

명시적 구현인 경우 private만 가능하기 때문에 클래스의 인스턴스로는 메소드 호출을 할 수 없고 인터페이스 타입으로 호출해야 합니다.

using System;
using System.Collections.Generic;
using System.Linq;

interface SamsungRemoteControl {
    void TurnOn();
    void TurnOff();
    void Fold();
}

interface LGRemoteControl {
    void TurnOn();
    void TurnOff();
    void Roll();
}

class IntegratedRemoteControl: SamsungRemoteControl, LGRemoteControl {
    void SamsungRemoteControl.TurnOn() { Console.WriteLine("Samsung Trun On"); }
    void SamsungRemoteControl.TurnOff() { Console.WriteLine("Samsung Trun Off"); }
    void LGRemoteControl.TurnOn() { Console.WriteLine("LG Trun On"); }
    void LGRemoteControl.TurnOff() { Console.WriteLine("LG Trun Off"); }
    
    public void Fold() { Console.WriteLine("Folding"); }
    public void Roll() { Console.WriteLine("Rolling"); }
}

class MainClass {
    static void Main() {
        SamsungRemoteControl src = new IntegratedRemoteControl();
        src.TurnOn();
        src.Fold();
        
        LGRemoteControl lrc = new IntegratedRemoteControl();
        lrc.TurnOn();
        lrc.Roll();
    }
}

실행결과

반응형
반응형

 

Electron으로 화면에 hello world를 표기하는 초간단 프로그램을 개발하는 과정입니다.
저처럼 Electron 초보자 수준에서 작성합니다.
또한 저는 윈도우즈 10 환경이므로 Mac이나 Linux에서는 일부 다를 수 있습니다.

1. Node.js 설치

Electron은 Node.js 기반으로 개발을 하기 때문에 제일 먼저 Node.js를 설치해야 합니다.
Node.js 공식 사이트에서 운영체체에 맞는 설치 파일을 내려받아 설치합니다.

nodejs.org/ko/

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

Current Version은 안정성에 문제가 있을 수 있으므로 가능한 LTS버전 설치를 권장합니다. 물론 Live환경이 아닌 학습 목적의 새로운 기능을 적극적으로 시험해 보려면 Current Version을 사용하면 됩니다.

2. package.json 만들기

cmd(terminal) 창에서 임의의 작업용 폴더를 생성하고 해당 폴더로 이동 후 npm init를 하면 초기 상태의 package.json 파일이 생성됩니다 (나오는 질문에 모두 enter를 치면 default value로 답변되어 작성됩니다). 

mkdir helloworld
cd helloworld
npm init

생성된 package.json은 다음과 같이 되어 있습니다.

package.json

3. Electron 설치하기

npm을 이용하여 electron을 설치합니다.

npm install electron --save-dev

4. index.html, index.js 작성 하기

index.html 파일

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello world</title>
</head>
<body>
<h1>Hello world</h1>
</body>
</html>

index.js 파일

const {app, BrowserWindow} = require("electron");

let win;

function createWindow() {
  win = new BrowserWindow({width: 800, height: 600});
  win.loadURL('file://' + __dirname + '/index.html');
  win.on("closed", () => {win = null;});
}

app.on("ready", createWindow);
app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
  }
});

app.on("activate", () => {
  if (win === null) {
    createWindow();
  }
});

5. 작성된 프로그램 실행

cmd 창에서 작성된 프로그램을 실행합니다.

node_modules\.bin\electron .

이상 Electron으로 만들어 본 첫번째 저의 프로그램 작성기 였습니다.

 

 

반응형
반응형

SQL서버에서는 VALUES를 기존 INSERT 문에서의 행의 값을 나열하는 목적 이외에 다양하게 활용이 가능한데 이 부분을 정리해 보겠습니다.

INSERT .. VALUES

가장 일반적으로 INSERT 할 데이터의 값을 나열하는 데 사용될 수 있습니다.

INSERT INTO Production.UnitMeasure  
VALUES (N'FT', N'Feet', '20080414'); 

SQL서버 2008 이상에서는 VALUES가 다중 행의 값을 지정할 수 있습니다.
INSERT .. VALUES로 한 번에 여러 행(최대 1,000행 까지)을 삽입할 수 있습니다.

INSERT INTO Production.UnitMeasure  
VALUES (N'FT2', N'Square Feet ', '20080923'), (N'Y', N'Yards', '20080923')
    , (N'Y3', N'Cubic Yards', '20080923'); 

VALUES 다음에 하나의 행을 하나의 괄호로 묶고 쉼표로 구분해야 합니다.

VALUES의 괄호 안에 올 수 있는 값은 상수, 변수 또는 식입니다(단, 식은 EXECUTE 문을 포함할 수 없습니다).
따라서 다음과 같이 사용자 정의 함수를 사용할 수도 있습니다.

INSERT INTO MyTable
VALUES (1, dbo.MyFunc(10, 20)),
       (2, dbo.MyFunc(30, 40))

식이 가능하기 때문 다른 SELECT문이 포함될 수도 있습니다.

INSERT INTO dbo.MyProducts (Name, ListPrice)  
VALUES ('Helmet', 25.50),  
       ('Wheel', 30.00),  
       ((SELECT Name FROM Production.Product WHERE ProductID = 720),  
        (SELECT ListPrice FROM Production.Product WHERE ProductID = 720));  

SELECT .. FROM (VALUES)

INSERT뿐 아니라 SELECT의 FROM절에서도 VALUES를 사용할 수 있는데 일종의 가상 파생 테이블과 같다고 볼 수 있겠습니다.

SELECT a, b FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a, b);

실행결과

앞서 INSERT .. VALUES에서 설명드린 것처럼 하나의 행을 하나의 괄호로 묶고 쉼표로 구분하면 됩니다.

CROSS APPLY (VALUES)

CROSS APPLY 의 VALUES에서 공급받은 행의 값을 이용하여 다양하게 활용할 수 있습니다.

CREATE TABLE #temp
(
    col1 int
,   col2 int
,   col3 int
,   col4 int
,   col5 int
)
INSERT #temp VALUES(1,2,3,4,5), (10,20,30,40,50)

SELECT 
    CASE WHEN a.col1 = b.col THEN b.col END AS col1,
    CASE WHEN a.col2 = b.col THEN b.col END AS col2,
    CASE WHEN a.col3 = b.col THEN b.col END AS col3,
    CASE WHEN a.col4 = b.col THEN b.col END AS col4,
    CASE WHEN a.col5 = b.col THEN b.col END AS col5
FROM #temp a
    CROSS APPLY (VALUES (a.col1),(a.col2),(a.col3),(a.col4),(a.col5)) b (col)

실행결과

CREATE TABLE #temp
(
    col1 int
,   col2 int
,   col3 int
,   col4 int
,   col5 int
)
INSERT #temp VALUES(1,2,3,4,5), (10,20,30,40,50)

SELECT 
    a.*, b.total
FROM 
    #temp a 
    CROSS APPLY 
    (
        SELECT SUM(x) total 
        FROM (VALUES (a.col1), (a.col2), (a.col3), (a.col4), (a.col5)) MyTable (x)
    ) b

실행결과

MERGE .. USING (VALUES)

MERGE문의 USING에 VALUES를 통해서 파생 원본 테이블로 사용할 수 있습니다.

MERGE INTO Sales.SalesReason AS Target  
USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'), ('Internet', 'Promotion'))  
       AS Source (NewName, NewReasonType)  
ON Target.Name = Source.NewName  
WHEN MATCHED THEN  
UPDATE SET ReasonType = Source.NewReasonType  
WHEN NOT MATCHED BY TARGET THEN  
INSERT (Name, ReasonType) VALUES (NewName, NewReasonType)  
OUTPUT $action INTO @SummaryOfChanges;  

(응용) 열 데이터에 대하여 집계 함수 사용

다음과 같이 열 데이터를 행으로 전환하는데 VALUES를 이용하여 한 행의 여러 칼럼 값들에 대하여 집계 함수를 사용할 수 있습니다.

CREATE TABLE #temp
(
    col1 int
,   col2 int
,   col3 int
,   col4 int
,   col5 int
)
INSERT #temp VALUES(4,1,8,10,57), (17,21,130,12,48)

SELECT 
    col1, col2, col3, col4, col5
,   (   SELECT AVG(a) 
        FROM (VALUES (col1), (col2), (col3), (col4), (col5)) x(a)
    ) average
FROM #temp

실행결과

이 글이 도움이 되셨으면 추천과 댓글을 부탁드려요!

[참조]

INSERT(Transact-SQL)
테이블 값 생성자(Transact-SQL)

 
 
 
 
반응형
반응형

정기적으로 로그 백업을 하고 있다면 로그 파일 크기 내에서 재활용은 하겠지만, 대량의 트랜잭션이 발생하여 로그파일의 크기가 늘어나더라도 로그 백업을 통해 이미 늘어난 파일 크기가 줄어들지는 않습니다. 이로 인해서 불필요하게 디스크 공간을 차지하게 되므로 가끔씩 로그파일 크기를 줄여줄 필요가 있습니다.

현재 로그파일 크기 확인

sp_helpfile

sp_helpfile로 확인해 보면 현재 로그파일 크기가 9,024,448 KB로 나타납니다 (운영 중인 DB라 가렸습니다).

이는 탐색기에서 확인되는 사이즈와 동일합니다.

VLF 구성 확인

DBCC loginfo

DBCC loginfo로 로그파일의 VLF(가상 로그 파일)를 확인해 보면 81개로 구성되어 있음을 알 수 있습니다.

로그파일 크기 줄이기

sp_helpfile 조회 결과의 'name' 컬럼에 해당하는 이름이 로그파일명 입니다.

DBCC SHRINKFILE (로그파일명)

DBCC SHRINKFILE 명령이 정상적으로 수행되면 다음과 같이 결과를 보여 줍니다.

위에서 CurrentSize는 줄어든 후 로그파일의 페이지 수를 나타냅니다. SQL 서버에서 한 페이지는 8KB 이므로 KB로 변경하면 1,025,504 * 8 = 8,204,032 가 됩니다.

sp_helpfile로 다시 확인해보면 다음과 같습니다.

작업 직전에 로그 백업을 받고 진행하지 않아서 많이 줄어들지는 않았지만 그래도 크기가 줄어들었습니다.

DBCC loginfo로 재확인 해보면 VLF 개수가 80개로 줄었습니다.

참고로 쿼리로 로그 테이블의 초기 사이즈를 확인하기 위해서는 다음과 같이 하면 됩니다.

SELECT name, size * 8 AS init_size_KB, physical_name
FROM master.sys.master_files where database_id = DB_ID('데이터베이스명')

DBCC SHRINKFILE를 통해 줄어들 수 있는 최대치는 이 초기 사이즈이기 때문에 이하로는 줄어들지 않습니다.

[참조]

DBCC SHRINKFILE(Transact-SQL)

반응형

+ Recent posts