두 테이블 간 조인을 할때 NOT IN 조건으로 JOIN 을 할 경우 처리하는 방법이다.

아래 예제 에서는 B 테이블의 value 컬럼의 내용을 NOT IN 조건으로 처리한다.

1. 

SELECT  A.*
FROM    A LEFT JOIN B ON A.value = B.value
WHERE   B.value IS NULL


2.

SELECT  A.*
FROM    A
WHERE   value NOT IN
(
SELECT  value
FROM    B
)

3.

SELECT  A.*
FROM    A
WHERE   NOT EXISTS
(
SELECT  value
FROM    B
WHERE   B.value = A.value
)


value 컬럼이 인덱스처리가 된 경우 성능차이는 없다고 한다.

그러나 value 컬럼이 NOT NULL임을 보장하지 않는 경우 하위 쿼리 결과 집합에 NULL 값이 있는지 여부에 따라 

다른 결과가 생성되므로 NOT IN 대신 LEFT JOIN / IS NULL 또는 NOT EXISTS를 사용해야한다.

참고

https://explainextended.com/2009/09/17/not-in-vs-not-exists-vs-left-join-is-null-oracle/

아래 코드를 이용하면 캡쳐를 방지할 수 있습니다.

using System;

using System.Drawing;

using System.Runtime.InteropServices;

using System.Windows.Forms;


namespace WindowsFormsApp

{

    public partial class MainForm : Form

    {

        private const uint WDA_NONE = 0;

        private const uint WDA_MONITOR = 1;


        [DllImport("user32.dll")]

        private static extern uint SetWindowDisplayAffinity(IntPtr windowHandle, uint affinity);


        public MainForm()

        {

            InitializeComponent();


            this.onButton.Click  += OnButton_Click;

            this.offButton.Click += OffButton_Click;

        }


        private void OnButton_Click(object sender, EventArgs e)

        {

            this.onButton.BackColor  = Color.White;

            this.offButton.BackColor = Color.Transparent;


            SetWindowDisplayAffinity(this.Handle, WDA_MONITOR);

        }


        private void OffButton_Click(object sender, EventArgs e)

        {

            this.onButton.BackColor  = Color.Transparent;

            this.offButton.BackColor = Color.White;


            SetWindowDisplayAffinity(this.Handle, WDA_NONE);

        }

    }

}



* 캡쳐도구를 이용해 캡쳐방지를 하지 않고 했을 때와  캡쳐방지를 켜고 했을 때 비교

(캡쳐방지를 켠 경우에는 녹화할 때도 검게변한다^^)


반디캠, 칼무리, 캡쳐도구, Print Screen 을 이용해 캡쳐 동작을 취할경우 검은 화면으로 보이게 된다.

메서드 호출시 메서드 안에서 어디에서 호출된 것인지 알고 싶을때가 있다

특히 로그 남길 때 유용하게 쓸수 있다.

아래 코드 처럼 메서드 인자로 [CallerMemberName], [CallerFilePath], [CallerLineNumber] 를 선언해 주면 알아서 내용이 들어가게된다.


using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Forms;

namespace CompilerServicesTest
{
    public partial class TestForm : Form
    {
        public TestForm()
        {
            InitializeComponent();

            CallMethod();
        }

        private void CallMethod()
        {
            WriteLog("CompilerServices Test!!");
        }

        private void WriteLog(string message,
           [CallerMemberName] string memberName = "",
           [CallerFilePath]   string sourceFilePath = "",
           [CallerLineNumber] int sourceLineNumber = 0)
        {
            Trace.WriteLine("message: " + message);
            Trace.WriteLine("member name: " + memberName);
            Trace.WriteLine("source file path: " + sourceFilePath);
            Trace.WriteLine("source line number: " + sourceLineNumber);
        }
    }
}



참고

https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/attributes/caller-information

+ Recent posts